Create a new boot/ directory
authorSimon Glass <sjg@chromium.org>
Thu, 14 Oct 2021 18:47:54 +0000 (12:47 -0600)
committerTom Rini <trini@konsulko.com>
Fri, 12 Nov 2021 00:01:56 +0000 (19:01 -0500)
Quite a lot of the code in common/relates to booting and images. Before
adding more it seems like a good time to move the code into its own
directory.

Most files with 'boot' or 'image' in them are moved, except:

- autoboot.c which relates to U-Boot automatically running a script
- bootstage.c which relates to U-Boot timing

Drop the removal of boot* files from the output directory, since this
interfers with the symlinks created by tools and there does not appear
to be any such file from my brief testing.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Artem Lapkin <email2tema@gmail.com>
Tested-by: Artem Lapkin <email2tema@gmail.com>
45 files changed:
Kconfig
Makefile
README
boot/Kconfig [new file with mode: 0644]
boot/Makefile [new file with mode: 0644]
boot/android_ab.c [new file with mode: 0644]
boot/boot_fit.c [new file with mode: 0644]
boot/bootm.c [new file with mode: 0644]
boot/bootm_os.c [new file with mode: 0644]
boot/bootretry.c [new file with mode: 0644]
boot/common_fit.c [new file with mode: 0644]
boot/fdt_region.c [new file with mode: 0644]
boot/image-android-dt.c [new file with mode: 0644]
boot/image-android.c [new file with mode: 0644]
boot/image-board.c [new file with mode: 0644]
boot/image-cipher.c [new file with mode: 0644]
boot/image-fdt.c [new file with mode: 0644]
boot/image-fit-sig.c [new file with mode: 0644]
boot/image-fit.c [new file with mode: 0644]
boot/image-host.c [new file with mode: 0644]
boot/image-sig.c [new file with mode: 0644]
boot/image.c [new file with mode: 0644]
common/Kconfig
common/Kconfig.boot [deleted file]
common/Makefile
common/android_ab.c [deleted file]
common/boot_fit.c [deleted file]
common/bootm.c [deleted file]
common/bootm_os.c [deleted file]
common/bootretry.c [deleted file]
common/common_fit.c [deleted file]
common/fdt_region.c [deleted file]
common/image-android-dt.c [deleted file]
common/image-android.c [deleted file]
common/image-board.c [deleted file]
common/image-cipher.c [deleted file]
common/image-fdt.c [deleted file]
common/image-fit-sig.c [deleted file]
common/image-fit.c [deleted file]
common/image-host.c [deleted file]
common/image-sig.c [deleted file]
common/image.c [deleted file]
doc/android/boot-image.rst
scripts/Makefile.spl
tools/Makefile

diff --git a/Kconfig b/Kconfig
index 931a22806e4ea54c0255319a18f2426e94dc067d..c46f4fce8625dffc1a27db186b91d6e8a42707a2 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -466,6 +466,8 @@ endmenu             # General setup
 
 source "api/Kconfig"
 
+source "boot/Kconfig"
+
 source "common/Kconfig"
 
 source "cmd/Kconfig"
index ea884fec26f95966fd99491d7441f08731f59086..299cd3ffac97a12667b045e0591c529634222378 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -808,6 +808,7 @@ HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makef
 
 libs-$(CONFIG_API) += api/
 libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
+libs-y += boot/
 libs-y += cmd/
 libs-y += common/
 libs-$(CONFIG_OF_EMBED) += dts/
@@ -2104,7 +2105,7 @@ CLEAN_DIRS  += $(MODVERDIR) \
                        $(filter-out include, $(shell ls -1 $d 2>/dev/null))))
 
 CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h tools/version.h \
-              boot* u-boot* MLO* SPL System.map fit-dtb.blob* \
+              u-boot* MLO* SPL System.map fit-dtb.blob* \
               u-boot-ivt.img.log u-boot-dtb.imx.log SPL.log u-boot.imx.log \
               lpc32xx-* bl31.c bl31.elf bl31_*.bin image.map tispl.bin* \
               idbloader.img flash.bin flash.log defconfig keep-syms-lto.c
diff --git a/README b/README
index 0f52888171554ac015ca130f5a6b008319193a2e..0a719333606e7867ee71381db35421f61b84ea28 100644 (file)
--- a/README
+++ b/README
@@ -144,6 +144,7 @@ Directory Hierarchy:
   /xtensa              Files generic to Xtensa architecture
 /api                   Machine/arch-independent API for external apps
 /board                 Board-dependent files
+/boot                  Support for images and booting
 /cmd                   U-Boot commands functions
 /common                        Misc architecture-independent functions
 /configs               Board default configuration files
diff --git a/boot/Kconfig b/boot/Kconfig
new file mode 100644 (file)
index 0000000..a8d4be2
--- /dev/null
@@ -0,0 +1,1036 @@
+menu "Boot options"
+
+menu "Boot images"
+
+config ANDROID_BOOT_IMAGE
+       bool "Enable support for Android Boot Images"
+       default y if FASTBOOT
+       help
+         This enables support for booting images which use the Android
+         image format header.
+
+config FIT
+       bool "Support Flattened Image Tree"
+       select HASH
+       select MD5
+       select SHA1
+       imply SHA256
+       help
+         This option allows you to boot the new uImage structure,
+         Flattened Image Tree.  FIT is formally a FDT, which can include
+         images of various types (kernel, FDT blob, ramdisk, etc.)
+         in a single blob.  To boot this new uImage structure,
+         pass the address of the blob to the "bootm" command.
+         FIT is very flexible, supporting compression, multiple images,
+         multiple configurations, verification through hashing and also
+         verified boot (secure boot using RSA).
+
+if FIT
+
+config FIT_EXTERNAL_OFFSET
+       hex "FIT external data offset"
+       default 0x0
+       help
+         This specifies a data offset in fit image.
+         The offset is from data payload offset to the beginning of
+         fit image header. When specifies a offset, specific data
+         could be put in the hole between data payload and fit image
+         header, such as CSF data on i.MX platform.
+
+config FIT_FULL_CHECK
+       bool "Do a full check of the FIT before using it"
+       default y
+       help
+         Enable this do a full check of the FIT to make sure it is valid. This
+         helps to protect against carefully crafted FITs which take advantage
+         of bugs or omissions in the code. This includes a bad structure,
+         multiple root nodes and the like.
+
+config FIT_SIGNATURE
+       bool "Enable signature verification of FIT uImages"
+       depends on DM
+       select HASH
+       imply RSA
+       imply RSA_VERIFY
+       select IMAGE_SIGN_INFO
+       select FIT_FULL_CHECK
+       help
+         This option enables signature verification of FIT uImages,
+         using a hash signed and verified using RSA. If
+         CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
+         hashing is available using hardware, then the RSA library will use
+         it. See doc/uImage.FIT/signature.txt for more details.
+
+         WARNING: When relying on signed FIT images with a required signature
+         check the legacy image format is disabled by default, so that
+         unsigned images cannot be loaded. If a board needs the legacy image
+         format support in this case, enable it using
+         CONFIG_LEGACY_IMAGE_FORMAT.
+
+config FIT_SIGNATURE_MAX_SIZE
+       hex "Max size of signed FIT structures"
+       depends on FIT_SIGNATURE
+       default 0x10000000
+       help
+         This option sets a max size in bytes for verified FIT uImages.
+         A sane value of 256MB protects corrupted DTB structures from overlapping
+         device memory. Assure this size does not extend past expected storage
+         space.
+
+config FIT_RSASSA_PSS
+       bool "Support rsassa-pss signature scheme of FIT image contents"
+       depends on FIT_SIGNATURE
+       help
+         Enable this to support the pss padding algorithm as described
+         in the rfc8017 (https://tools.ietf.org/html/rfc8017).
+
+config FIT_CIPHER
+       bool "Enable ciphering data in a FIT uImages"
+       depends on DM
+       select AES
+       help
+         Enable the feature of data ciphering/unciphering in the tool mkimage
+         and in the u-boot support of the FIT image.
+
+config FIT_VERBOSE
+       bool "Show verbose messages when FIT images fail"
+       help
+         Generally a system will have valid FIT images so debug messages
+         are a waste of code space. If you are debugging your images then
+         you can enable this option to get more verbose information about
+         failures.
+
+config FIT_BEST_MATCH
+       bool "Select the best match for the kernel device tree"
+       help
+         When no configuration is explicitly selected, default to the
+         one whose fdt's compatibility field best matches that of
+         U-Boot itself. A match is considered "best" if it matches the
+         most specific compatibility entry of U-Boot's fdt's root node.
+         The order of entries in the configuration's fdt is ignored.
+
+config FIT_IMAGE_POST_PROCESS
+       bool "Enable post-processing of FIT artifacts after loading by U-Boot"
+       depends on TI_SECURE_DEVICE || SOCFPGA_SECURE_VAB_AUTH
+       help
+         Allows doing any sort of manipulation to blobs after they got extracted
+         from FIT images like stripping off headers or modifying the size of the
+         blob, verification, authentication, decryption etc. in a platform or
+         board specific way. In order to use this feature a platform or board-
+         specific implementation of board_fit_image_post_process() must be
+         provided. Also, anything done during this post-processing step would
+         need to be comprehended in how the images were prepared before being
+         injected into the FIT creation (i.e. the blobs would have been pre-
+         processed before being added to the FIT image).
+
+config FIT_PRINT
+        bool "Support FIT printing"
+        default y
+        help
+          Support printing the content of the fitImage in a verbose manner.
+
+if SPL
+
+config SPL_FIT
+       bool "Support Flattened Image Tree within SPL"
+       depends on SPL
+       select SPL_HASH
+       select SPL_OF_LIBFDT
+
+config SPL_FIT_PRINT
+       bool "Support FIT printing within SPL"
+       depends on SPL_FIT
+       help
+         Support printing the content of the fitImage in a verbose manner in SPL.
+
+config SPL_FIT_FULL_CHECK
+       bool "Do a full check of the FIT before using it"
+       help
+         Enable this do a full check of the FIT to make sure it is valid. This
+         helps to protect against carefully crafted FITs which take advantage
+         of bugs or omissions in the code. This includes a bad structure,
+         multiple root nodes and the like.
+
+
+config SPL_FIT_SIGNATURE
+       bool "Enable signature verification of FIT firmware within SPL"
+       depends on SPL_DM
+       depends on SPL_LOAD_FIT || SPL_LOAD_FIT_FULL
+       select FIT_SIGNATURE
+       select SPL_FIT
+       select SPL_CRYPTO
+       select SPL_HASH
+       imply SPL_RSA
+       imply SPL_RSA_VERIFY
+       select SPL_IMAGE_SIGN_INFO
+       select SPL_FIT_FULL_CHECK
+
+config SPL_FIT_SIGNATURE_MAX_SIZE
+       hex "Max size of signed FIT structures in SPL"
+       depends on SPL_FIT_SIGNATURE
+       default 0x10000000
+       help
+         This option sets a max size in bytes for verified FIT uImages.
+         A sane value of 256MB protects corrupted DTB structures from overlapping
+         device memory. Assure this size does not extend past expected storage
+         space.
+
+config SPL_FIT_RSASSA_PSS
+       bool "Support rsassa-pss signature scheme of FIT image contents in SPL"
+       depends on SPL_FIT_SIGNATURE
+       help
+         Enable this to support the pss padding algorithm as described
+         in the rfc8017 (https://tools.ietf.org/html/rfc8017) in SPL.
+
+config SPL_LOAD_FIT
+       bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
+       select SPL_FIT
+       help
+         Normally with the SPL framework a legacy image is generated as part
+         of the build. This contains U-Boot along with information as to
+         where it should be loaded. This option instead enables generation
+         of a FIT (Flat Image Tree) which provides more flexibility. In
+         particular it can handle selecting from multiple device tree
+         and passing the correct one to U-Boot.
+
+         This path has the following limitations:
+
+         1. "loadables" images, other than FDTs, which do not have a "load"
+            property will not be loaded. This limitation also applies to FPGA
+            images with the correct "compatible" string.
+         2. For FPGA images, only the "compatible" = "u-boot,fpga-legacy"
+            loading method is supported.
+         3. FDTs are only loaded for images with an "os" property of "u-boot".
+            "linux" images are also supported with Falcon boot mode.
+
+config SPL_LOAD_FIT_ADDRESS
+       hex "load address of fit image"
+       depends on SPL_LOAD_FIT
+       default 0x0
+       help
+         Specify the load address of the fit image that will be loaded
+         by SPL.
+
+config SPL_LOAD_FIT_APPLY_OVERLAY
+       bool "Enable SPL applying DT overlays from FIT"
+       depends on SPL_LOAD_FIT
+       select OF_LIBFDT_OVERLAY
+       help
+         The device tree is loaded from the FIT image. Allow the SPL is to
+         also load device-tree overlays from the FIT image an apply them
+         over the device tree.
+
+config SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ
+       depends on SPL_LOAD_FIT_APPLY_OVERLAY
+       default 0x10000
+       hex "size of temporary buffer used to load the overlays"
+       help
+         The size of the area where the overlays will be loaded and
+         uncompress. Must be at least as large as biggest overlay
+         (uncompressed)
+
+config SPL_LOAD_FIT_FULL
+       bool "Enable SPL loading U-Boot as a FIT (full fitImage features)"
+       select SPL_FIT
+       help
+         Normally with the SPL framework a legacy image is generated as part
+         of the build. This contains U-Boot along with information as to
+         where it should be loaded. This option instead enables generation
+         of a FIT (Flat Image Tree) which provides more flexibility. In
+         particular it can handle selecting from multiple device tree
+         and passing the correct one to U-Boot.
+
+config SPL_FIT_IMAGE_POST_PROCESS
+       bool "Enable post-processing of FIT artifacts after loading by the SPL"
+       depends on SPL_LOAD_FIT
+       help
+         Allows doing any sort of manipulation to blobs after they got extracted
+         from the U-Boot FIT image like stripping off headers or modifying the
+         size of the blob, verification, authentication, decryption etc. in a
+         platform or board specific way. In order to use this feature a platform
+         or board-specific implementation of board_fit_image_post_process() must
+         be provided. Also, anything done during this post-processing step would
+         need to be comprehended in how the images were prepared before being
+         injected into the FIT creation (i.e. the blobs would have been pre-
+         processed before being added to the FIT image).
+
+config SPL_FIT_SOURCE
+       string ".its source file for U-Boot FIT image"
+       depends on SPL_FIT
+       help
+         Specifies a (platform specific) FIT source file to generate the
+         U-Boot FIT image. This could specify further image to load and/or
+         execute.
+
+config USE_SPL_FIT_GENERATOR
+       bool "Use a script to generate the .its script"
+       default y if SPL_FIT && (!ARCH_SUNXI && !RISCV)
+
+config SPL_FIT_GENERATOR
+       string ".its file generator script for U-Boot FIT image"
+       depends on USE_SPL_FIT_GENERATOR
+       default "arch/arm/mach-rockchip/make_fit_atf.py" if SPL_LOAD_FIT && ARCH_ROCKCHIP
+       default "arch/arm/mach-zynqmp/mkimage_fit_atf.sh" if SPL_LOAD_FIT && ARCH_ZYNQMP
+       help
+         Specifies a (platform specific) script file to generate the FIT
+         source file used to build the U-Boot FIT image file. This gets
+         passed a list of supported device tree file stub names to
+         include in the generated image.
+
+endif # SPL
+
+endif # FIT
+
+config LEGACY_IMAGE_FORMAT
+       bool "Enable support for the legacy image format"
+       default y if !FIT_SIGNATURE
+       help
+         This option enables the legacy image format. It is enabled by
+         default for backward compatibility, unless FIT_SIGNATURE is
+         set where it is disabled so that unsigned images cannot be
+         loaded. If a board needs the legacy image format support in this
+         case, enable it here.
+
+config SUPPORT_RAW_INITRD
+       bool "Enable raw initrd images"
+       help
+         Note, defining the SUPPORT_RAW_INITRD allows user to supply
+         kernel with raw initrd images. The syntax is slightly different, the
+         address of the initrd must be augmented by it's size, in the following
+         format: "<initrd address>:<initrd size>".
+
+config OF_BOARD_SETUP
+       bool "Set up board-specific details in device tree before boot"
+       depends on OF_LIBFDT
+       help
+         This causes U-Boot to call ft_board_setup() before booting into
+         the Operating System. This function can set up various
+         board-specific information in the device tree for use by the OS.
+         The device tree is then passed to the OS.
+
+config OF_SYSTEM_SETUP
+       bool "Set up system-specific details in device tree before boot"
+       depends on OF_LIBFDT
+       help
+         This causes U-Boot to call ft_system_setup() before booting into
+         the Operating System. This function can set up various
+         system-specific information in the device tree for use by the OS.
+         The device tree is then passed to the OS.
+
+config OF_STDOUT_VIA_ALIAS
+       bool "Update the device-tree stdout alias from U-Boot"
+       depends on OF_LIBFDT
+       help
+         This uses U-Boot's serial alias from the aliases node to update
+         the device tree passed to the OS. The "linux,stdout-path" property
+         in the chosen node is set to point to the correct serial node.
+         This option currently references CONFIG_CONS_INDEX, which is
+         incorrect when used with device tree as this option does not
+         exist / should not be used.
+
+config SYS_EXTRA_OPTIONS
+       string "Extra Options (DEPRECATED)"
+       help
+         The old configuration infrastructure (= mkconfig + boards.cfg)
+         provided the extra options field. If you have something like
+         "HAS_BAR,BAZ=64", the optional options
+           #define CONFIG_HAS
+           #define CONFIG_BAZ  64
+         will be defined in include/config.h.
+         This option was prepared for the smooth migration from the old
+         configuration to Kconfig. Since this option will be removed sometime,
+         new boards should not use this option.
+
+config HAVE_SYS_TEXT_BASE
+       bool
+       depends on !NIOS2 && !XTENSA
+       depends on !EFI_APP
+       default y
+
+config SYS_TEXT_BASE
+       depends on HAVE_SYS_TEXT_BASE
+       default 0x0 if POSITION_INDEPENDENT
+       default 0x80800000 if ARCH_OMAP2PLUS || ARCH_K3
+       default 0x4a000000 if ARCH_SUNXI && !MACH_SUN9I && !MACH_SUN8I_V3S
+       default 0x2a000000 if ARCH_SUNXI && MACH_SUN9I
+       default 0x42e00000 if ARCH_SUNXI && MACH_SUN8I_V3S
+       hex "Text Base"
+       help
+         The address in memory that U-Boot will be running from, initially.
+
+config SYS_CLK_FREQ
+       depends on ARC || ARCH_SUNXI || MPC83xx
+       int "CPU clock frequency"
+       help
+         TODO: Move CONFIG_SYS_CLK_FREQ for all the architecture
+
+config ARCH_FIXUP_FDT_MEMORY
+       bool "Enable arch_fixup_memory_banks() call"
+       default y
+       help
+         Enable FDT memory map syncup before OS boot. This feature can be
+         used for booting OS with different memory setup where the part of
+         the memory location should be used for different purpose.
+
+config CHROMEOS
+       bool "Support booting Chrome OS"
+       help
+         Chrome OS requires U-Boot to set up a table indicating the boot mode
+         (e.g. Developer mode) and a few other things. Enable this if you are
+         booting on a Chromebook to avoid getting an error about an invalid
+         firmware ID.
+
+config CHROMEOS_VBOOT
+       bool "Support Chrome OS verified boot"
+       help
+         This is intended to enable the full Chrome OS verified boot support
+         in U-Boot. It is not actually implemented in the U-Boot source code
+         at present, so this option is always set to 'n'. It allows
+         distinguishing between booting Chrome OS in a basic way (developer
+         mode) and a full boot.
+
+config RAMBOOT_PBL
+       bool "Freescale PBL(pre-boot loader) image format support"
+       help
+         Some SoCs use PBL to load RCW and/or pre-initialization instructions.
+         For more details refer to doc/README.pblimage
+
+config SYS_FSL_PBL_PBI
+       string "PBI(pre-boot instructions) commands for the PBL image"
+       depends on RAMBOOT_PBL
+       help
+         PBI commands can be used to configure SoC before it starts the execution.
+         Please refer doc/README.pblimage for more details.
+
+config SYS_FSL_PBL_RCW
+       string "Aadditional RCW (Power on reset configuration) for the PBL image"
+       depends on RAMBOOT_PBL
+       help
+         Enables addition of RCW (Power on reset configuration) in built image.
+         Please refer doc/README.pblimage for more details.
+
+endmenu                # Boot images
+
+menu "Boot timing"
+
+config BOOTSTAGE
+       bool "Boot timing and reporting"
+       help
+         Enable recording of boot time while booting. To use it, insert
+         calls to bootstage_mark() with a suitable BOOTSTAGE_ID from
+         bootstage.h. Only a single entry is recorded for each ID. You can
+         give the entry a name with bootstage_mark_name(). You can also
+         record elapsed time in a particular stage using bootstage_start()
+         before starting and bootstage_accum() when finished. Bootstage will
+         add up all the accumulated time and report it.
+
+         Normally, IDs are defined in bootstage.h but a small number of
+         additional 'user' IDs can be used by passing BOOTSTAGE_ID_ALLOC
+         as the ID.
+
+         Calls to show_boot_progress() will also result in log entries but
+         these will not have names.
+
+config SPL_BOOTSTAGE
+       bool "Boot timing and reported in SPL"
+       depends on BOOTSTAGE
+       help
+         Enable recording of boot time in SPL. To make this visible to U-Boot
+         proper, enable BOOTSTAGE_STASH as well. This will stash the timing
+         information when SPL finishes and load it when U-Boot proper starts
+         up.
+
+config TPL_BOOTSTAGE
+       bool "Boot timing and reported in TPL"
+       depends on BOOTSTAGE
+       help
+         Enable recording of boot time in SPL. To make this visible to U-Boot
+         proper, enable BOOTSTAGE_STASH as well. This will stash the timing
+         information when TPL finishes and load it when U-Boot proper starts
+         up.
+
+config BOOTSTAGE_REPORT
+       bool "Display a detailed boot timing report before booting the OS"
+       depends on BOOTSTAGE
+       help
+         Enable output of a boot time report just before the OS is booted.
+         This shows how long it took U-Boot to go through each stage of the
+         boot process. The report looks something like this:
+
+               Timer summary in microseconds:
+                      Mark    Elapsed  Stage
+                         0          0  reset
+                 3,575,678  3,575,678  board_init_f start
+                 3,575,695         17  arch_cpu_init A9
+                 3,575,777         82  arch_cpu_init done
+                 3,659,598     83,821  board_init_r start
+                 3,910,375    250,777  main_loop
+                29,916,167 26,005,792  bootm_start
+                30,361,327    445,160  start_kernel
+
+config BOOTSTAGE_RECORD_COUNT
+       int "Number of boot stage records to store"
+       depends on BOOTSTAGE
+       default 30
+       help
+         This is the size of the bootstage record list and is the maximum
+         number of bootstage records that can be recorded.
+
+config SPL_BOOTSTAGE_RECORD_COUNT
+       int "Number of boot stage records to store for SPL"
+       depends on SPL_BOOTSTAGE
+       default 5
+       help
+         This is the size of the bootstage record list and is the maximum
+         number of bootstage records that can be recorded.
+
+config TPL_BOOTSTAGE_RECORD_COUNT
+       int "Number of boot stage records to store for TPL"
+       depends on TPL_BOOTSTAGE
+       default 5
+       help
+         This is the size of the bootstage record list and is the maximum
+         number of bootstage records that can be recorded.
+
+config BOOTSTAGE_FDT
+       bool "Store boot timing information in the OS device tree"
+       depends on BOOTSTAGE
+       help
+         Stash the bootstage information in the FDT. A root 'bootstage'
+         node is created with each bootstage id as a child. Each child
+         has a 'name' property and either 'mark' containing the
+         mark time in microseconds, or 'accum' containing the
+         accumulated time for that bootstage id in microseconds.
+         For example:
+
+               bootstage {
+                       154 {
+                               name = "board_init_f";
+                               mark = <3575678>;
+                       };
+                       170 {
+                               name = "lcd";
+                               accum = <33482>;
+                       };
+               };
+
+         Code in the Linux kernel can find this in /proc/devicetree.
+
+config BOOTSTAGE_STASH
+       bool "Stash the boot timing information in memory before booting OS"
+       depends on BOOTSTAGE
+       help
+         Some OSes do not support device tree. Bootstage can instead write
+         the boot timing information in a binary format at a given address.
+         This happens through a call to bootstage_stash(), typically in
+         the CPU's cleanup_before_linux() function. You can use the
+         'bootstage stash' and 'bootstage unstash' commands to do this on
+         the command line.
+
+config BOOTSTAGE_STASH_ADDR
+       hex "Address to stash boot timing information"
+       default 0
+       help
+         Provide an address which will not be overwritten by the OS when it
+         starts, so that it can read this information when ready.
+
+config BOOTSTAGE_STASH_SIZE
+       hex "Size of boot timing stash region"
+       default 0x1000
+       help
+         This should be large enough to hold the bootstage stash. A value of
+         4096 (4KiB) is normally plenty.
+
+config SHOW_BOOT_PROGRESS
+       bool "Show boot progress in a board-specific manner"
+       help
+         Defining this option allows to add some board-specific code (calling
+         a user-provided function show_boot_progress(int) that enables you to
+         show the system's boot progress on some display (for example, some
+         LEDs) on your board. At the moment, the following checkpoints are
+         implemented:
+
+         Legacy uImage format:
+
+         Arg   Where                   When
+           1   common/cmd_bootm.c      before attempting to boot an image
+          -1   common/cmd_bootm.c      Image header has bad     magic number
+           2   common/cmd_bootm.c      Image header has correct magic number
+          -2   common/cmd_bootm.c      Image header has bad     checksum
+           3   common/cmd_bootm.c      Image header has correct checksum
+          -3   common/cmd_bootm.c      Image data   has bad     checksum
+           4   common/cmd_bootm.c      Image data   has correct checksum
+          -4   common/cmd_bootm.c      Image is for unsupported architecture
+           5   common/cmd_bootm.c      Architecture check OK
+          -5   common/cmd_bootm.c      Wrong Image Type (not kernel, multi)
+           6   common/cmd_bootm.c      Image Type check OK
+          -6   common/cmd_bootm.c      gunzip uncompression error
+          -7   common/cmd_bootm.c      Unimplemented compression type
+           7   common/cmd_bootm.c      Uncompression OK
+           8   common/cmd_bootm.c      No uncompress/copy overwrite error
+          -9   common/cmd_bootm.c      Unsupported OS (not Linux, BSD, VxWorks, QNX)
+
+           9   common/image.c          Start initial ramdisk verification
+         -10   common/image.c          Ramdisk header has bad     magic number
+         -11   common/image.c          Ramdisk header has bad     checksum
+          10   common/image.c          Ramdisk header is OK
+         -12   common/image.c          Ramdisk data   has bad     checksum
+          11   common/image.c          Ramdisk data   has correct checksum
+          12   common/image.c          Ramdisk verification complete, start loading
+         -13   common/image.c          Wrong Image Type (not PPC Linux ramdisk)
+          13   common/image.c          Start multifile image verification
+          14   common/image.c          No initial ramdisk, no multifile, continue.
+
+          15   arch/<arch>/lib/bootm.c All preparation done, transferring control to OS
+
+         -30   arch/powerpc/lib/board.c        Fatal error, hang the system
+         -31   post/post.c             POST test failed, detected by post_output_backlog()
+         -32   post/post.c             POST test failed, detected by post_run_single()
+
+          34   common/cmd_doc.c        before loading a Image from a DOC device
+         -35   common/cmd_doc.c        Bad usage of "doc" command
+          35   common/cmd_doc.c        correct usage of "doc" command
+         -36   common/cmd_doc.c        No boot device
+          36   common/cmd_doc.c        correct boot device
+         -37   common/cmd_doc.c        Unknown Chip ID on boot device
+          37   common/cmd_doc.c        correct chip ID found, device available
+         -38   common/cmd_doc.c        Read Error on boot device
+          38   common/cmd_doc.c        reading Image header from DOC device OK
+         -39   common/cmd_doc.c        Image header has bad magic number
+          39   common/cmd_doc.c        Image header has correct magic number
+         -40   common/cmd_doc.c        Error reading Image from DOC device
+          40   common/cmd_doc.c        Image header has correct magic number
+          41   common/cmd_ide.c        before loading a Image from a IDE device
+         -42   common/cmd_ide.c        Bad usage of "ide" command
+          42   common/cmd_ide.c        correct usage of "ide" command
+         -43   common/cmd_ide.c        No boot device
+          43   common/cmd_ide.c        boot device found
+         -44   common/cmd_ide.c        Device not available
+          44   common/cmd_ide.c        Device available
+         -45   common/cmd_ide.c        wrong partition selected
+          45   common/cmd_ide.c        partition selected
+         -46   common/cmd_ide.c        Unknown partition table
+          46   common/cmd_ide.c        valid partition table found
+         -47   common/cmd_ide.c        Invalid partition type
+          47   common/cmd_ide.c        correct partition type
+         -48   common/cmd_ide.c        Error reading Image Header on boot device
+          48   common/cmd_ide.c        reading Image Header from IDE device OK
+         -49   common/cmd_ide.c        Image header has bad magic number
+          49   common/cmd_ide.c        Image header has correct magic number
+         -50   common/cmd_ide.c        Image header has bad     checksum
+          50   common/cmd_ide.c        Image header has correct checksum
+         -51   common/cmd_ide.c        Error reading Image from IDE device
+          51   common/cmd_ide.c        reading Image from IDE device OK
+          52   common/cmd_nand.c       before loading a Image from a NAND device
+         -53   common/cmd_nand.c       Bad usage of "nand" command
+          53   common/cmd_nand.c       correct usage of "nand" command
+         -54   common/cmd_nand.c       No boot device
+          54   common/cmd_nand.c       boot device found
+         -55   common/cmd_nand.c       Unknown Chip ID on boot device
+          55   common/cmd_nand.c       correct chip ID found, device available
+         -56   common/cmd_nand.c       Error reading Image Header on boot device
+          56   common/cmd_nand.c       reading Image Header from NAND device OK
+         -57   common/cmd_nand.c       Image header has bad magic number
+          57   common/cmd_nand.c       Image header has correct magic number
+         -58   common/cmd_nand.c       Error reading Image from NAND device
+          58   common/cmd_nand.c       reading Image from NAND device OK
+
+         -60   common/env_common.c     Environment has a bad CRC, using default
+
+          64   net/eth.c               starting with Ethernet configuration.
+         -64   net/eth.c               no Ethernet found.
+          65   net/eth.c               Ethernet found.
+
+         -80   common/cmd_net.c        usage wrong
+          80   common/cmd_net.c        before calling net_loop()
+         -81   common/cmd_net.c        some error in net_loop() occurred
+          81   common/cmd_net.c        net_loop() back without error
+         -82   common/cmd_net.c        size == 0 (File with size 0 loaded)
+          82   common/cmd_net.c        trying automatic boot
+          83   common/cmd_net.c        running "source" command
+         -83   common/cmd_net.c        some error in automatic boot or "source" command
+          84   common/cmd_net.c        end without errors
+
+         FIT uImage format:
+
+         Arg   Where                   When
+         100   common/cmd_bootm.c      Kernel FIT Image has correct format
+         -100  common/cmd_bootm.c      Kernel FIT Image has incorrect format
+         101   common/cmd_bootm.c      No Kernel subimage unit name, using configuration
+         -101  common/cmd_bootm.c      Can't get configuration for kernel subimage
+         102   common/cmd_bootm.c      Kernel unit name specified
+         -103  common/cmd_bootm.c      Can't get kernel subimage node offset
+         103   common/cmd_bootm.c      Found configuration node
+         104   common/cmd_bootm.c      Got kernel subimage node offset
+         -104  common/cmd_bootm.c      Kernel subimage hash verification failed
+         105   common/cmd_bootm.c      Kernel subimage hash verification OK
+         -105  common/cmd_bootm.c      Kernel subimage is for unsupported architecture
+         106   common/cmd_bootm.c      Architecture check OK
+         -106  common/cmd_bootm.c      Kernel subimage has wrong type
+         107   common/cmd_bootm.c      Kernel subimage type OK
+         -107  common/cmd_bootm.c      Can't get kernel subimage data/size
+         108   common/cmd_bootm.c      Got kernel subimage data/size
+         -108  common/cmd_bootm.c      Wrong image type (not legacy, FIT)
+         -109  common/cmd_bootm.c      Can't get kernel subimage type
+         -110  common/cmd_bootm.c      Can't get kernel subimage comp
+         -111  common/cmd_bootm.c      Can't get kernel subimage os
+         -112  common/cmd_bootm.c      Can't get kernel subimage load address
+         -113  common/cmd_bootm.c      Image uncompress/copy overwrite error
+
+         120   common/image.c          Start initial ramdisk verification
+         -120  common/image.c          Ramdisk FIT image has incorrect format
+         121   common/image.c          Ramdisk FIT image has correct format
+         122   common/image.c          No ramdisk subimage unit name, using configuration
+         -122  common/image.c          Can't get configuration for ramdisk subimage
+         123   common/image.c          Ramdisk unit name specified
+         -124  common/image.c          Can't get ramdisk subimage node offset
+         125   common/image.c          Got ramdisk subimage node offset
+         -125  common/image.c          Ramdisk subimage hash verification failed
+         126   common/image.c          Ramdisk subimage hash verification OK
+         -126  common/image.c          Ramdisk subimage for unsupported architecture
+         127   common/image.c          Architecture check OK
+         -127  common/image.c          Can't get ramdisk subimage data/size
+         128   common/image.c          Got ramdisk subimage data/size
+         129   common/image.c          Can't get ramdisk load address
+         -129  common/image.c          Got ramdisk load address
+
+         -130  common/cmd_doc.c        Incorrect FIT image format
+         131   common/cmd_doc.c        FIT image format OK
+
+         -140  common/cmd_ide.c        Incorrect FIT image format
+         141   common/cmd_ide.c        FIT image format OK
+
+         -150  common/cmd_nand.c       Incorrect FIT image format
+         151   common/cmd_nand.c       FIT image format OK
+
+config SPL_SHOW_BOOT_PROGRESS
+       bool "Show boot progress in a board-specific manner"
+       depends on SPL
+       help
+         Defining this option allows to add some board-specific code (calling
+         a user-provided function show_boot_progress(int) that enables you to
+         show the system's boot progress on some display (for example, some
+         LEDs) on your board. For details see SHOW_BOOT_PROGRESS.
+
+endmenu
+
+menu "Boot media"
+
+config NOR_BOOT
+       bool "Support for booting from NOR flash"
+       depends on NOR
+       help
+         Enabling this will make a U-Boot binary that is capable of being
+         booted via NOR.  In this case we will enable certain pinmux early
+         as the ROM only partially sets up pinmux.  We also default to using
+         NOR for environment.
+
+config NAND_BOOT
+       bool "Support for booting from NAND flash"
+       imply MTD_RAW_NAND
+       help
+         Enabling this will make a U-Boot binary that is capable of being
+         booted via NAND flash. This is not a must, some SoCs need this,
+         some not.
+
+config ONENAND_BOOT
+       bool "Support for booting from ONENAND"
+       imply MTD_RAW_NAND
+       help
+         Enabling this will make a U-Boot binary that is capable of being
+         booted via ONENAND. This is not a must, some SoCs need this,
+         some not.
+
+config QSPI_BOOT
+       bool "Support for booting from QSPI flash"
+       help
+         Enabling this will make a U-Boot binary that is capable of being
+         booted via QSPI flash. This is not a must, some SoCs need this,
+         some not.
+
+config SATA_BOOT
+       bool "Support for booting from SATA"
+       help
+         Enabling this will make a U-Boot binary that is capable of being
+         booted via SATA. This is not a must, some SoCs need this,
+         some not.
+
+config SD_BOOT
+       bool "Support for booting from SD/EMMC"
+       help
+         Enabling this will make a U-Boot binary that is capable of being
+         booted via SD/EMMC. This is not a must, some SoCs need this,
+         some not.
+
+config SPI_BOOT
+       bool "Support for booting from SPI flash"
+       help
+         Enabling this will make a U-Boot binary that is capable of being
+         booted via SPI flash. This is not a must, some SoCs need this,
+         some not.
+
+endmenu
+
+menu "Autoboot options"
+
+config AUTOBOOT
+       bool "Autoboot"
+       default y
+       help
+         This enables the autoboot.  See doc/README.autoboot for detail.
+
+config BOOTDELAY
+       int "delay in seconds before automatically booting"
+       default 2
+       depends on AUTOBOOT
+       help
+         Delay before automatically running bootcmd;
+         set to 0 to autoboot with no delay, but you can stop it by key input.
+         set to -1 to disable autoboot.
+         set to -2 to autoboot with no delay and not check for abort
+
+         If this value is >= 0 then it is also used for the default delay
+         before starting the default entry in bootmenu. If it is < 0 then
+         a default value of 10s is used.
+
+         See doc/README.autoboot for details.
+
+config AUTOBOOT_KEYED
+       bool "Stop autobooting via specific input key / string"
+       help
+         This option enables stopping (aborting) of the automatic
+         boot feature only by issuing a specific input key or
+         string. If not enabled, any input key will abort the
+         U-Boot automatic booting process and bring the device
+         to the U-Boot prompt for user input.
+
+config AUTOBOOT_FLUSH_STDIN
+       bool "Enable flushing stdin before starting to read the password"
+       depends on AUTOBOOT_KEYED && !SANDBOX
+       help
+         When this option is enabled stdin buffer will be flushed before
+         starting to read the password.
+         This can't be enabled for the sandbox as flushing stdin would
+         break the autoboot unit tests.
+
+config AUTOBOOT_PROMPT
+       string "Autoboot stop prompt"
+       depends on AUTOBOOT_KEYED
+       default "Autoboot in %d seconds\\n"
+       help
+         This string is displayed before the boot delay selected by
+         CONFIG_BOOTDELAY starts. If it is not defined there is no
+         output indicating that autoboot is in progress.
+
+         Note that this define is used as the (only) argument to a
+         printf() call, so it may contain '%' format specifications,
+         provided that it also includes, sepearated by commas exactly
+         like in a printf statement, the required arguments. It is
+         the responsibility of the user to select only such arguments
+         that are valid in the given context.
+
+config AUTOBOOT_ENCRYPTION
+       bool "Enable encryption in autoboot stopping"
+       depends on AUTOBOOT_KEYED
+       help
+         This option allows a string to be entered into U-Boot to stop the
+         autoboot.
+         The behavior depends whether CONFIG_CRYPT_PW from lib is enabled
+         or not.
+         In case CONFIG_CRYPT_PW is enabled, the string will be forwarded
+         to the crypt-based functionality and be compared against the
+         string in the environment variable 'bootstopkeycrypt'.
+         In case CONFIG_CRYPT_PW is disabled the string itself is hashed
+         and compared against the hash in the environment variable
+         'bootstopkeysha256'.
+         If it matches in either case then boot stops and
+         a command-line prompt is presented.
+         This provides a way to ship a secure production device which can also
+         be accessed at the U-Boot command line.
+
+config AUTOBOOT_SHA256_FALLBACK
+       bool "Allow fallback from crypt-hashed password to sha256"
+       depends on AUTOBOOT_ENCRYPTION && CRYPT_PW
+       help
+         This option adds support to fall back from crypt-hashed
+         passwords to checking a SHA256 hashed password in case the
+         'bootstopusesha256' environment variable is set to 'true'.
+
+config AUTOBOOT_DELAY_STR
+       string "Delay autobooting via specific input key / string"
+       depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION
+       help
+         This option delays the automatic boot feature by issuing
+         a specific input key or string. If CONFIG_AUTOBOOT_DELAY_STR
+         or the environment variable "bootdelaykey" is specified
+         and this string is received from console input before
+         autoboot starts booting, U-Boot gives a command prompt. The
+         U-Boot prompt will time out if CONFIG_BOOT_RETRY_TIME is
+         used, otherwise it never times out.
+
+config AUTOBOOT_STOP_STR
+       string "Stop autobooting via specific input key / string"
+       depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION
+       help
+         This option enables stopping (aborting) of the automatic
+         boot feature only by issuing a specific input key or
+         string. If CONFIG_AUTOBOOT_STOP_STR or the environment
+         variable "bootstopkey" is specified and this string is
+         received from console input before autoboot starts booting,
+         U-Boot gives a command prompt. The U-Boot prompt never
+         times out, even if CONFIG_BOOT_RETRY_TIME is used.
+
+config AUTOBOOT_KEYED_CTRLC
+       bool "Enable Ctrl-C autoboot interruption"
+       depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION
+       help
+         This option allows for the boot sequence to be interrupted
+         by ctrl-c, in addition to the "bootdelaykey" and "bootstopkey".
+         Setting this variable provides an escape sequence from the
+         limited "password" strings.
+
+config AUTOBOOT_NEVER_TIMEOUT
+       bool "Make the password entry never time-out"
+       depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION && CRYPT_PW
+       help
+         This option removes the timeout from the password entry
+         when the user first presses the <Enter> key before entering
+         any other character.
+
+config AUTOBOOT_STOP_STR_ENABLE
+       bool "Enable fixed string to stop autobooting"
+       depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION
+       help
+         This option enables the feature to add a fixed stop
+         string that is defined at compile time.
+         In every case it will be tried to load the stop
+         string from the environment.
+         In case this is enabled and there is no stop string
+         in the environment, this will be used as default value.
+
+config AUTOBOOT_STOP_STR_CRYPT
+       string "Stop autobooting via crypt-hashed password"
+       depends on AUTOBOOT_STOP_STR_ENABLE && CRYPT_PW
+       help
+         This option adds the feature to only stop the autobooting,
+         and therefore boot into the U-Boot prompt, when the input
+         string / password matches a values that is hashed via
+         one of the supported crypt-style password hashing options
+         and saved in the environment variable "bootstopkeycrypt".
+
+config AUTOBOOT_STOP_STR_SHA256
+       string "Stop autobooting via SHA256 hashed password"
+       depends on AUTOBOOT_STOP_STR_ENABLE
+       help
+         This option adds the feature to only stop the autobooting,
+         and therefore boot into the U-Boot prompt, when the input
+         string / password matches a values that is encypted via
+         a SHA256 hash and saved in the environment variable
+         "bootstopkeysha256". If the value in that variable
+         includes a ":", the portion prior to the ":" will be treated
+         as a salt value.
+
+config AUTOBOOT_USE_MENUKEY
+       bool "Allow a specify key to run a menu from the environment"
+       depends on !AUTOBOOT_KEYED
+       help
+         If a specific key is pressed to stop autoboot, then the commands in
+         the environment variable 'menucmd' are executed before boot starts.
+
+config AUTOBOOT_MENUKEY
+       int "ASCII value of boot key to show a menu"
+       default 0
+       depends on AUTOBOOT_USE_MENUKEY
+       help
+         If this key is pressed to stop autoboot, then the commands in the
+         environment variable 'menucmd' will be executed before boot starts.
+         For example, 33 means "!" in ASCII, so pressing ! at boot would take
+         this action.
+
+config AUTOBOOT_MENU_SHOW
+       bool "Show a menu on boot"
+       depends on CMD_BOOTMENU
+       help
+         This enables the boot menu, controlled by environment variables
+         defined by the board. The menu starts after running the 'preboot'
+         environmnent variable (if enabled) and before handling the boot delay.
+         See README.bootmenu for more details.
+
+endmenu
+
+config USE_BOOTARGS
+       bool "Enable boot arguments"
+       help
+         Provide boot arguments to bootm command. Boot arguments are specified
+         in CONFIG_BOOTARGS option. Enable this option to be able to specify
+         CONFIG_BOOTARGS string. If this option is disabled, CONFIG_BOOTARGS
+         will be undefined and won't take any space in U-Boot image.
+
+config BOOTARGS
+       string "Boot arguments"
+       depends on USE_BOOTARGS && !USE_DEFAULT_ENV_FILE
+       help
+         This can be used to pass arguments to the bootm command. The value of
+         CONFIG_BOOTARGS goes into the environment value "bootargs". Note that
+         this value will also override the "chosen" node in FDT blob.
+
+config BOOTARGS_SUBST
+       bool "Support substituting strings in boot arguments"
+       help
+         This allows substituting string values in the boot arguments. These
+         are applied after the commandline has been built.
+
+         One use for this is to insert the root-disk UUID into the command
+         line where bootargs contains "root=${uuid}"
+
+               setenv bootargs "console= root=${uuid}"
+               # Set the 'uuid' environment variable
+               part uuid mmc 2:2 uuid
+
+               # Command-line substitution will put the real uuid into the
+               # kernel command line
+               bootm
+
+config USE_BOOTCOMMAND
+       bool "Enable a default value for bootcmd"
+       help
+         Provide a default value for the bootcmd entry in the environment.  If
+         autoboot is enabled this is what will be run automatically.  Enable
+         this option to be able to specify CONFIG_BOOTCOMMAND as a string.  If
+         this option is disabled, CONFIG_BOOTCOMMAND will be undefined and
+         won't take any space in U-Boot image.
+
+config BOOTCOMMAND
+       string "bootcmd value"
+       depends on USE_BOOTCOMMAND && !USE_DEFAULT_ENV_FILE
+       default "run distro_bootcmd" if DISTRO_DEFAULTS
+       help
+         This is the string of commands that will be used as bootcmd and if
+         AUTOBOOT is set, automatically run.
+
+config USE_PREBOOT
+       bool "Enable preboot"
+       help
+         When this option is enabled, the existence of the environment
+         variable "preboot" will be checked immediately before starting the
+         CONFIG_BOOTDELAY countdown and/or running the auto-boot command resp.
+         entering interactive mode.
+
+         This feature is especially useful when "preboot" is automatically
+         generated or modified. For example, the boot code can modify the
+         "preboot" when a user holds down a certain combination of keys.
+
+config PREBOOT
+       string "preboot default value"
+       depends on USE_PREBOOT && !USE_DEFAULT_ENV_FILE
+       default "usb start" if USB_KEYBOARD
+       default ""
+       help
+         This is the default of "preboot" environment variable.
+
+config DEFAULT_FDT_FILE
+       string "Default fdt file"
+       help
+         This option is used to set the default fdt file to boot OS.
+
+endmenu                # Booting
diff --git a/boot/Makefile b/boot/Makefile
new file mode 100644 (file)
index 0000000..a19e85c
--- /dev/null
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2004-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+ifndef CONFIG_SPL_BUILD
+
+# This option is not just y/n - it can have a numeric value
+ifdef CONFIG_BOOT_RETRY_TIME
+obj-y += bootretry.o
+endif
+
+obj-$(CONFIG_CMD_BOOTM) += bootm.o bootm_os.o
+obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o
+obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
+
+endif
+
+obj-y += image.o image-board.o
+obj-$(CONFIG_ANDROID_AB) += android_ab.o
+obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
+obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
+obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += fdt_region.o
+obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
+obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
+obj-$(CONFIG_$(SPL_TPL_)IMAGE_SIGN_INFO) += image-sig.o
+obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-fit-sig.o
+obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o
+
+obj-$(CONFIG_CMD_ADTIMG) += image-android-dt.o
+
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
+endif
diff --git a/boot/android_ab.c b/boot/android_ab.c
new file mode 100644 (file)
index 0000000..4943f26
--- /dev/null
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ */
+#include <common.h>
+#include <android_ab.h>
+#include <android_bootloader_message.h>
+#include <blk.h>
+#include <log.h>
+#include <malloc.h>
+#include <part.h>
+#include <memalign.h>
+#include <linux/err.h>
+#include <u-boot/crc.h>
+#include <u-boot/crc.h>
+
+/**
+ * Compute the CRC-32 of the bootloader control struct.
+ *
+ * Only the bytes up to the crc32_le field are considered for the CRC-32
+ * calculation.
+ *
+ * @param[in] abc bootloader control block
+ *
+ * @return crc32 sum
+ */
+static uint32_t ab_control_compute_crc(struct bootloader_control *abc)
+{
+       return crc32(0, (void *)abc, offsetof(typeof(*abc), crc32_le));
+}
+
+/**
+ * Initialize bootloader_control to the default value.
+ *
+ * It allows us to boot all slots in order from the first one. This value
+ * should be used when the bootloader message is corrupted, but not when
+ * a valid message indicates that all slots are unbootable.
+ *
+ * @param[in] abc bootloader control block
+ *
+ * @return 0 on success and a negative on error
+ */
+static int ab_control_default(struct bootloader_control *abc)
+{
+       int i;
+       const struct slot_metadata metadata = {
+               .priority = 15,
+               .tries_remaining = 7,
+               .successful_boot = 0,
+               .verity_corrupted = 0,
+               .reserved = 0
+       };
+
+       if (!abc)
+               return -EFAULT;
+
+       memcpy(abc->slot_suffix, "a\0\0\0", 4);
+       abc->magic = BOOT_CTRL_MAGIC;
+       abc->version = BOOT_CTRL_VERSION;
+       abc->nb_slot = NUM_SLOTS;
+       memset(abc->reserved0, 0, sizeof(abc->reserved0));
+       for (i = 0; i < abc->nb_slot; ++i)
+               abc->slot_info[i] = metadata;
+
+       memset(abc->reserved1, 0, sizeof(abc->reserved1));
+       abc->crc32_le = ab_control_compute_crc(abc);
+
+       return 0;
+}
+
+/**
+ * Load the boot_control struct from disk into newly allocated memory.
+ *
+ * This function allocates and returns an integer number of disk blocks,
+ * based on the block size of the passed device to help performing a
+ * read-modify-write operation on the boot_control struct.
+ * The boot_control struct offset (2 KiB) must be a multiple of the device
+ * block size, for simplicity.
+ *
+ * @param[in] dev_desc Device where to read the boot_control struct from
+ * @param[in] part_info Partition in 'dev_desc' where to read from, normally
+ *                     the "misc" partition should be used
+ * @param[out] pointer to pointer to bootloader_control data
+ * @return 0 on success and a negative on error
+ */
+static int ab_control_create_from_disk(struct blk_desc *dev_desc,
+                                      const struct disk_partition *part_info,
+                                      struct bootloader_control **abc)
+{
+       ulong abc_offset, abc_blocks, ret;
+
+       abc_offset = offsetof(struct bootloader_message_ab, slot_suffix);
+       if (abc_offset % part_info->blksz) {
+               log_err("ANDROID: Boot control block not block aligned.\n");
+               return -EINVAL;
+       }
+       abc_offset /= part_info->blksz;
+
+       abc_blocks = DIV_ROUND_UP(sizeof(struct bootloader_control),
+                                 part_info->blksz);
+       if (abc_offset + abc_blocks > part_info->size) {
+               log_err("ANDROID: boot control partition too small. Need at");
+               log_err(" least %lu blocks but have %lu blocks.\n",
+                       abc_offset + abc_blocks, part_info->size);
+               return -EINVAL;
+       }
+       *abc = malloc_cache_aligned(abc_blocks * part_info->blksz);
+       if (!*abc)
+               return -ENOMEM;
+
+       ret = blk_dread(dev_desc, part_info->start + abc_offset, abc_blocks,
+                       *abc);
+       if (IS_ERR_VALUE(ret)) {
+               log_err("ANDROID: Could not read from boot ctrl partition\n");
+               free(*abc);
+               return -EIO;
+       }
+
+       log_debug("ANDROID: Loaded ABC, %lu blocks\n", abc_blocks);
+
+       return 0;
+}
+
+/**
+ * Store the loaded boot_control block.
+ *
+ * Store back to the same location it was read from with
+ * ab_control_create_from_misc().
+ *
+ * @param[in] dev_desc Device where we should write the boot_control struct
+ * @param[in] part_info Partition on the 'dev_desc' where to write
+ * @param[in] abc Pointer to the boot control struct and the extra bytes after
+ *                it up to the nearest block boundary
+ * @return 0 on success and a negative on error
+ */
+static int ab_control_store(struct blk_desc *dev_desc,
+                           const struct disk_partition *part_info,
+                           struct bootloader_control *abc)
+{
+       ulong abc_offset, abc_blocks, ret;
+
+       abc_offset = offsetof(struct bootloader_message_ab, slot_suffix) /
+                    part_info->blksz;
+       abc_blocks = DIV_ROUND_UP(sizeof(struct bootloader_control),
+                                 part_info->blksz);
+       ret = blk_dwrite(dev_desc, part_info->start + abc_offset, abc_blocks,
+                        abc);
+       if (IS_ERR_VALUE(ret)) {
+               log_err("ANDROID: Could not write back the misc partition\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/**
+ * Compare two slots.
+ *
+ * The function determines slot which is should we boot from among the two.
+ *
+ * @param[in] a The first bootable slot metadata
+ * @param[in] b The second bootable slot metadata
+ * @return Negative if the slot "a" is better, positive of the slot "b" is
+ *         better or 0 if they are equally good.
+ */
+static int ab_compare_slots(const struct slot_metadata *a,
+                           const struct slot_metadata *b)
+{
+       /* Higher priority is better */
+       if (a->priority != b->priority)
+               return b->priority - a->priority;
+
+       /* Higher successful_boot value is better, in case of same priority */
+       if (a->successful_boot != b->successful_boot)
+               return b->successful_boot - a->successful_boot;
+
+       /* Higher tries_remaining is better to ensure round-robin */
+       if (a->tries_remaining != b->tries_remaining)
+               return b->tries_remaining - a->tries_remaining;
+
+       return 0;
+}
+
+int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info)
+{
+       struct bootloader_control *abc = NULL;
+       u32 crc32_le;
+       int slot, i, ret;
+       bool store_needed = false;
+       char slot_suffix[4];
+
+       ret = ab_control_create_from_disk(dev_desc, part_info, &abc);
+       if (ret < 0) {
+               /*
+                * This condition represents an actual problem with the code or
+                * the board setup, like an invalid partition information.
+                * Signal a repair mode and do not try to boot from either slot.
+                */
+               return ret;
+       }
+
+       crc32_le = ab_control_compute_crc(abc);
+       if (abc->crc32_le != crc32_le) {
+               log_err("ANDROID: Invalid CRC-32 (expected %.8x, found %.8x),",
+                       crc32_le, abc->crc32_le);
+               log_err("re-initializing A/B metadata.\n");
+
+               ret = ab_control_default(abc);
+               if (ret < 0) {
+                       free(abc);
+                       return -ENODATA;
+               }
+               store_needed = true;
+       }
+
+       if (abc->magic != BOOT_CTRL_MAGIC) {
+               log_err("ANDROID: Unknown A/B metadata: %.8x\n", abc->magic);
+               free(abc);
+               return -ENODATA;
+       }
+
+       if (abc->version > BOOT_CTRL_VERSION) {
+               log_err("ANDROID: Unsupported A/B metadata version: %.8x\n",
+                       abc->version);
+               free(abc);
+               return -ENODATA;
+       }
+
+       /*
+        * At this point a valid boot control metadata is stored in abc,
+        * followed by other reserved data in the same block. We select a with
+        * the higher priority slot that
+        *  - is not marked as corrupted and
+        *  - either has tries_remaining > 0 or successful_boot is true.
+        * If the selected slot has a false successful_boot, we also decrement
+        * the tries_remaining until it eventually becomes unbootable because
+        * tries_remaining reaches 0. This mechanism produces a bootloader
+        * induced rollback, typically right after a failed update.
+        */
+
+       /* Safety check: limit the number of slots. */
+       if (abc->nb_slot > ARRAY_SIZE(abc->slot_info)) {
+               abc->nb_slot = ARRAY_SIZE(abc->slot_info);
+               store_needed = true;
+       }
+
+       slot = -1;
+       for (i = 0; i < abc->nb_slot; ++i) {
+               if (abc->slot_info[i].verity_corrupted ||
+                   !abc->slot_info[i].tries_remaining) {
+                       log_debug("ANDROID: unbootable slot %d tries: %d, ",
+                                 i, abc->slot_info[i].tries_remaining);
+                       log_debug("corrupt: %d\n",
+                                 abc->slot_info[i].verity_corrupted);
+                       continue;
+               }
+               log_debug("ANDROID: bootable slot %d pri: %d, tries: %d, ",
+                         i, abc->slot_info[i].priority,
+                         abc->slot_info[i].tries_remaining);
+               log_debug("corrupt: %d, successful: %d\n",
+                         abc->slot_info[i].verity_corrupted,
+                         abc->slot_info[i].successful_boot);
+
+               if (slot < 0 ||
+                   ab_compare_slots(&abc->slot_info[i],
+                                    &abc->slot_info[slot]) < 0) {
+                       slot = i;
+               }
+       }
+
+       if (slot >= 0 && !abc->slot_info[slot].successful_boot) {
+               log_err("ANDROID: Attempting slot %c, tries remaining %d\n",
+                       BOOT_SLOT_NAME(slot),
+                       abc->slot_info[slot].tries_remaining);
+               abc->slot_info[slot].tries_remaining--;
+               store_needed = true;
+       }
+
+       if (slot >= 0) {
+               /*
+                * Legacy user-space requires this field to be set in the BCB.
+                * Newer releases load this slot suffix from the command line
+                * or the device tree.
+                */
+               memset(slot_suffix, 0, sizeof(slot_suffix));
+               slot_suffix[0] = BOOT_SLOT_NAME(slot);
+               if (memcmp(abc->slot_suffix, slot_suffix,
+                          sizeof(slot_suffix))) {
+                       memcpy(abc->slot_suffix, slot_suffix,
+                              sizeof(slot_suffix));
+                       store_needed = true;
+               }
+       }
+
+       if (store_needed) {
+               abc->crc32_le = ab_control_compute_crc(abc);
+               ab_control_store(dev_desc, part_info, abc);
+       }
+       free(abc);
+
+       if (slot < 0)
+               return -EINVAL;
+
+       return slot;
+}
diff --git a/boot/boot_fit.c b/boot/boot_fit.c
new file mode 100644 (file)
index 0000000..dfc2a31
--- /dev/null
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017
+ * Texas Instruments, <www.ti.com>
+ *
+ * Franklin S Cooper Jr. <fcooper@ti.com>
+ */
+
+#include <boot_fit.h>
+#include <common.h>
+#include <errno.h>
+#include <image.h>
+#include <log.h>
+#include <linux/libfdt.h>
+
+static int fdt_offset(const void *fit)
+{
+       int images, node, fdt_len, fdt_node, fdt_offset;
+       const char *fdt_name;
+
+       node = fit_find_config_node(fit);
+       if (node < 0)
+               return node;
+
+       images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (images < 0) {
+               debug("%s: Cannot find /images node: %d\n", __func__, images);
+               return -EINVAL;
+       }
+
+       fdt_name = fdt_getprop(fit, node, FIT_FDT_PROP, &fdt_len);
+       if (!fdt_name) {
+               debug("%s: Cannot find fdt name property: %d\n",
+                     __func__, fdt_len);
+               return -EINVAL;
+       }
+
+       fdt_node = fdt_subnode_offset(fit, images, fdt_name);
+       if (fdt_node < 0) {
+               debug("%s: Cannot find fdt node '%s': %d\n",
+                     __func__, fdt_name, fdt_node);
+               return -EINVAL;
+       }
+
+       fdt_offset = fdt_getprop_u32(fit, fdt_node, "data-offset");
+
+       if (fdt_offset == FDT_ERROR)
+               return -ENOENT;
+
+       fdt_len = fdt_getprop_u32(fit, fdt_node, "data-size");
+
+       if (fdt_len < 0)
+               return fdt_len;
+
+       return fdt_offset;
+}
+
+void *locate_dtb_in_fit(const void *fit)
+{
+       struct image_header *header;
+       int size;
+       int ret;
+
+       size = fdt_totalsize(fit);
+       size = (size + 3) & ~3;
+
+       header = (struct image_header *)fit;
+
+       if (image_get_magic(header) != FDT_MAGIC) {
+               debug("No FIT image appended to U-boot\n");
+               return NULL;
+       }
+
+       ret = fdt_offset(fit);
+
+       if (ret < 0)
+               return NULL;
+       else
+               return (void *)fit+size+ret;
+}
diff --git a/boot/bootm.c b/boot/bootm.c
new file mode 100644 (file)
index 0000000..4482f84
--- /dev/null
@@ -0,0 +1,1038 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2009
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <bootstage.h>
+#include <cli.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <errno.h>
+#include <fdt_support.h>
+#include <irq_func.h>
+#include <lmb.h>
+#include <log.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <net.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/sizes.h>
+#if defined(CONFIG_CMD_USB)
+#include <usb.h>
+#endif
+#else
+#include "mkimage.h"
+#endif
+
+#include <command.h>
+#include <bootm.h>
+#include <image.h>
+
+#ifndef CONFIG_SYS_BOOTM_LEN
+/* use 8MByte as default max gunzip size */
+#define CONFIG_SYS_BOOTM_LEN   0x800000
+#endif
+
+#define MAX_CMDLINE_SIZE       SZ_4K
+
+#define IH_INITRD_ARCH IH_ARCH_DEFAULT
+
+#ifndef USE_HOSTCC
+
+DECLARE_GLOBAL_DATA_PTR;
+
+bootm_headers_t images;                /* pointers to os/initrd/fdt images */
+
+static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
+                                  char *const argv[], bootm_headers_t *images,
+                                  ulong *os_data, ulong *os_len);
+
+__weak void board_quiesce_devices(void)
+{
+}
+
+#ifdef CONFIG_LMB
+static void boot_start_lmb(bootm_headers_t *images)
+{
+       ulong           mem_start;
+       phys_size_t     mem_size;
+
+       mem_start = env_get_bootm_low();
+       mem_size = env_get_bootm_size();
+
+       lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
+                                  mem_size, NULL);
+}
+#else
+#define lmb_reserve(lmb, base, size)
+static inline void boot_start_lmb(bootm_headers_t *images) { }
+#endif
+
+static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc,
+                      char *const argv[])
+{
+       memset((void *)&images, 0, sizeof(images));
+       images.verify = env_get_yesno("verify");
+
+       boot_start_lmb(&images);
+
+       bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
+       images.state = BOOTM_STATE_START;
+
+       return 0;
+}
+
+static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
+                        char *const argv[])
+{
+       const void *os_hdr;
+       bool ep_found = false;
+       int ret;
+
+       /* get kernel image header, start address and length */
+       os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
+                       &images, &images.os.image_start, &images.os.image_len);
+       if (images.os.image_len == 0) {
+               puts("ERROR: can't get kernel image!\n");
+               return 1;
+       }
+
+       /* get image parameters */
+       switch (genimg_get_format(os_hdr)) {
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
+       case IMAGE_FORMAT_LEGACY:
+               images.os.type = image_get_type(os_hdr);
+               images.os.comp = image_get_comp(os_hdr);
+               images.os.os = image_get_os(os_hdr);
+
+               images.os.end = image_get_image_end(os_hdr);
+               images.os.load = image_get_load(os_hdr);
+               images.os.arch = image_get_arch(os_hdr);
+               break;
+#endif
+#if CONFIG_IS_ENABLED(FIT)
+       case IMAGE_FORMAT_FIT:
+               if (fit_image_get_type(images.fit_hdr_os,
+                                      images.fit_noffset_os,
+                                      &images.os.type)) {
+                       puts("Can't get image type!\n");
+                       bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
+                       return 1;
+               }
+
+               if (fit_image_get_comp(images.fit_hdr_os,
+                                      images.fit_noffset_os,
+                                      &images.os.comp)) {
+                       puts("Can't get image compression!\n");
+                       bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
+                       return 1;
+               }
+
+               if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
+                                    &images.os.os)) {
+                       puts("Can't get image OS!\n");
+                       bootstage_error(BOOTSTAGE_ID_FIT_OS);
+                       return 1;
+               }
+
+               if (fit_image_get_arch(images.fit_hdr_os,
+                                      images.fit_noffset_os,
+                                      &images.os.arch)) {
+                       puts("Can't get image ARCH!\n");
+                       return 1;
+               }
+
+               images.os.end = fit_get_end(images.fit_hdr_os);
+
+               if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
+                                      &images.os.load)) {
+                       puts("Can't get image load address!\n");
+                       bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
+                       return 1;
+               }
+               break;
+#endif
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+       case IMAGE_FORMAT_ANDROID:
+               images.os.type = IH_TYPE_KERNEL;
+               images.os.comp = android_image_get_kcomp(os_hdr);
+               images.os.os = IH_OS_LINUX;
+
+               images.os.end = android_image_get_end(os_hdr);
+               images.os.load = android_image_get_kload(os_hdr);
+               images.ep = images.os.load;
+               ep_found = true;
+               break;
+#endif
+       default:
+               puts("ERROR: unknown image format type!\n");
+               return 1;
+       }
+
+       /* If we have a valid setup.bin, we will use that for entry (x86) */
+       if (images.os.arch == IH_ARCH_I386 ||
+           images.os.arch == IH_ARCH_X86_64) {
+               ulong len;
+
+               ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
+               if (ret < 0 && ret != -ENOENT) {
+                       puts("Could not find a valid setup.bin for x86\n");
+                       return 1;
+               }
+               /* Kernel entry point is the setup.bin */
+       } else if (images.legacy_hdr_valid) {
+               images.ep = image_get_ep(&images.legacy_hdr_os_copy);
+#if CONFIG_IS_ENABLED(FIT)
+       } else if (images.fit_uname_os) {
+               int ret;
+
+               ret = fit_image_get_entry(images.fit_hdr_os,
+                                         images.fit_noffset_os, &images.ep);
+               if (ret) {
+                       puts("Can't get entry point property!\n");
+                       return 1;
+               }
+#endif
+       } else if (!ep_found) {
+               puts("Could not find kernel entry point!\n");
+               return 1;
+       }
+
+       if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
+               if (CONFIG_IS_ENABLED(CMD_BOOTI) &&
+                   images.os.arch == IH_ARCH_ARM64) {
+                       ulong image_addr;
+                       ulong image_size;
+
+                       ret = booti_setup(images.os.image_start, &image_addr,
+                                         &image_size, true);
+                       if (ret != 0)
+                               return 1;
+
+                       images.os.type = IH_TYPE_KERNEL;
+                       images.os.load = image_addr;
+                       images.ep = image_addr;
+               } else {
+                       images.os.load = images.os.image_start;
+                       images.ep += images.os.image_start;
+               }
+       }
+
+       images.os.start = map_to_sysmem(os_hdr);
+
+       return 0;
+}
+
+/**
+ * bootm_find_images - wrapper to find and locate various images
+ * @flag: Ignored Argument
+ * @argc: command argument count
+ * @argv: command argument list
+ * @start: OS image start address
+ * @size: OS image size
+ *
+ * boot_find_images() will attempt to load an available ramdisk,
+ * flattened device tree, as well as specifically marked
+ * "loadable" images (loadables are FIT only)
+ *
+ * Note: bootm_find_images will skip an image if it is not found
+ *
+ * @return:
+ *     0, if all existing images were loaded correctly
+ *     1, if an image is found but corrupted, or invalid
+ */
+int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
+                     ulong size)
+{
+       int ret;
+
+       /* find ramdisk */
+       ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
+                              &images.rd_start, &images.rd_end);
+       if (ret) {
+               puts("Ramdisk image is corrupt or invalid\n");
+               return 1;
+       }
+
+       /* check if ramdisk overlaps OS image */
+       if (images.rd_start && (((ulong)images.rd_start >= start &&
+                                (ulong)images.rd_start < start + size) ||
+                               ((ulong)images.rd_end > start &&
+                                (ulong)images.rd_end <= start + size) ||
+                               ((ulong)images.rd_start < start &&
+                                (ulong)images.rd_end >= start + size))) {
+               printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n",
+                      start, start + size);
+               return 1;
+       }
+
+#if CONFIG_IS_ENABLED(OF_LIBFDT)
+       /* find flattened device tree */
+       ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
+                          &images.ft_addr, &images.ft_len);
+       if (ret) {
+               puts("Could not find a valid device tree\n");
+               return 1;
+       }
+
+       /* check if FDT overlaps OS image */
+       if (images.ft_addr &&
+           (((ulong)images.ft_addr >= start &&
+             (ulong)images.ft_addr <= start + size) ||
+            ((ulong)images.ft_addr + images.ft_len >= start &&
+             (ulong)images.ft_addr + images.ft_len <= start + size))) {
+               printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n",
+                      start, start + size);
+               return 1;
+       }
+
+       if (CONFIG_IS_ENABLED(CMD_FDT))
+               set_working_fdt_addr(map_to_sysmem(images.ft_addr));
+#endif
+
+#if CONFIG_IS_ENABLED(FIT)
+       if (IS_ENABLED(CONFIG_FPGA)) {
+               /* find bitstreams */
+               ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
+                                   NULL, NULL);
+               if (ret) {
+                       printf("FPGA image is corrupted or invalid\n");
+                       return 1;
+               }
+       }
+
+       /* find all of the loadables */
+       ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
+                              NULL, NULL);
+       if (ret) {
+               printf("Loadable(s) is corrupt or invalid\n");
+               return 1;
+       }
+#endif
+
+       return 0;
+}
+
+static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc,
+                           char *const argv[])
+{
+       if (((images.os.type == IH_TYPE_KERNEL) ||
+            (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
+            (images.os.type == IH_TYPE_MULTI)) &&
+           (images.os.os == IH_OS_LINUX ||
+                images.os.os == IH_OS_VXWORKS))
+               return bootm_find_images(flag, argc, argv, 0, 0);
+
+       return 0;
+}
+#endif /* USE_HOSTC */
+
+#if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE)
+/**
+ * handle_decomp_error() - display a decompression error
+ *
+ * This function tries to produce a useful message. In the case where the
+ * uncompressed size is the same as the available space, we can assume that
+ * the image is too large for the buffer.
+ *
+ * @comp_type:         Compression type being used (IH_COMP_...)
+ * @uncomp_size:       Number of bytes uncompressed
+ * @ret:               errno error code received from compression library
+ * @return Appropriate BOOTM_ERR_ error code
+ */
+static int handle_decomp_error(int comp_type, size_t uncomp_size, int ret)
+{
+       const char *name = genimg_get_comp_name(comp_type);
+
+       /* ENOSYS means unimplemented compression type, don't reset. */
+       if (ret == -ENOSYS)
+               return BOOTM_ERR_UNIMPLEMENTED;
+
+       if (uncomp_size >= CONFIG_SYS_BOOTM_LEN)
+               printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
+       else
+               printf("%s: uncompress error %d\n", name, ret);
+
+       /*
+        * The decompression routines are now safe, so will not write beyond
+        * their bounds. Probably it is not necessary to reset, but maintain
+        * the current behaviour for now.
+        */
+       printf("Must RESET board to recover\n");
+#ifndef USE_HOSTCC
+       bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
+#endif
+
+       return BOOTM_ERR_RESET;
+}
+#endif
+
+#ifndef USE_HOSTCC
+static int bootm_load_os(bootm_headers_t *images, int boot_progress)
+{
+       image_info_t os = images->os;
+       ulong load = os.load;
+       ulong load_end;
+       ulong blob_start = os.start;
+       ulong blob_end = os.end;
+       ulong image_start = os.image_start;
+       ulong image_len = os.image_len;
+       ulong flush_start = ALIGN_DOWN(load, ARCH_DMA_MINALIGN);
+       bool no_overlap;
+       void *load_buf, *image_buf;
+       int err;
+
+       load_buf = map_sysmem(load, 0);
+       image_buf = map_sysmem(os.image_start, image_len);
+       err = image_decomp(os.comp, load, os.image_start, os.type,
+                          load_buf, image_buf, image_len,
+                          CONFIG_SYS_BOOTM_LEN, &load_end);
+       if (err) {
+               err = handle_decomp_error(os.comp, load_end - load, err);
+               bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
+               return err;
+       }
+       /* We need the decompressed image size in the next steps */
+       images->os.image_len = load_end - load;
+
+       flush_cache(flush_start, ALIGN(load_end, ARCH_DMA_MINALIGN) - flush_start);
+
+       debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end);
+       bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
+
+       no_overlap = (os.comp == IH_COMP_NONE && load == image_start);
+
+       if (!no_overlap && load < blob_end && load_end > blob_start) {
+               debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
+                     blob_start, blob_end);
+               debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
+                     load_end);
+
+               /* Check what type of image this is. */
+               if (images->legacy_hdr_valid) {
+                       if (image_get_type(&images->legacy_hdr_os_copy)
+                                       == IH_TYPE_MULTI)
+                               puts("WARNING: legacy format multi component image overwritten\n");
+                       return BOOTM_ERR_OVERLAP;
+               } else {
+                       puts("ERROR: new format image overwritten - must RESET the board to recover\n");
+                       bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
+                       return BOOTM_ERR_RESET;
+               }
+       }
+
+       lmb_reserve(&images->lmb, images->os.load, (load_end -
+                                                   images->os.load));
+       return 0;
+}
+
+/**
+ * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
+ *
+ * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
+ *     enabled)
+ */
+ulong bootm_disable_interrupts(void)
+{
+       ulong iflag;
+
+       /*
+        * We have reached the point of no return: we are going to
+        * overwrite all exception vector code, so we cannot easily
+        * recover from any failures any more...
+        */
+       iflag = disable_interrupts();
+#ifdef CONFIG_NETCONSOLE
+       /* Stop the ethernet stack if NetConsole could have left it up */
+       eth_halt();
+# ifndef CONFIG_DM_ETH
+       eth_unregister(eth_get_dev());
+# endif
+#endif
+
+#if defined(CONFIG_CMD_USB)
+       /*
+        * turn off USB to prevent the host controller from writing to the
+        * SDRAM while Linux is booting. This could happen (at least for OHCI
+        * controller), because the HCCA (Host Controller Communication Area)
+        * lies within the SDRAM and the host controller writes continously to
+        * this area (as busmaster!). The HccaFrameNumber is for example
+        * updated every 1 ms within the HCCA structure in SDRAM! For more
+        * details see the OpenHCI specification.
+        */
+       usb_stop();
+#endif
+       return iflag;
+}
+
+#define CONSOLE_ARG            "console="
+#define CONSOLE_ARG_SIZE       sizeof(CONSOLE_ARG)
+
+/**
+ * fixup_silent_linux() - Handle silencing the linux boot if required
+ *
+ * This uses the silent_linux envvar to control whether to add/set a "console="
+ * parameter to the command line
+ *
+ * @buf: Buffer containing the string to process
+ * @maxlen: Maximum length of buffer
+ * @return 0 if OK, -ENOSPC if @maxlen is too small
+ */
+static int fixup_silent_linux(char *buf, int maxlen)
+{
+       int want_silent;
+       char *cmdline;
+       int size;
+
+       /*
+        * Move the input string to the end of buffer. The output string will be
+        * built up at the start.
+        */
+       size = strlen(buf) + 1;
+       if (size * 2 > maxlen)
+               return -ENOSPC;
+       cmdline = buf + maxlen - size;
+       memmove(cmdline, buf, size);
+       /*
+        * Only fix cmdline when requested. The environment variable can be:
+        *
+        *      no - we never fixup
+        *      yes - we always fixup
+        *      unset - we rely on the console silent flag
+        */
+       want_silent = env_get_yesno("silent_linux");
+       if (want_silent == 0)
+               return 0;
+       else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
+               return 0;
+
+       debug("before silent fix-up: %s\n", cmdline);
+       if (*cmdline) {
+               char *start = strstr(cmdline, CONSOLE_ARG);
+
+               /* Check space for maximum possible new command line */
+               if (size + CONSOLE_ARG_SIZE > maxlen)
+                       return -ENOSPC;
+
+               if (start) {
+                       char *end = strchr(start, ' ');
+                       int start_bytes;
+
+                       start_bytes = start - cmdline + CONSOLE_ARG_SIZE - 1;
+                       strncpy(buf, cmdline, start_bytes);
+                       if (end)
+                               strcpy(buf + start_bytes, end);
+                       else
+                               buf[start_bytes] = '\0';
+               } else {
+                       sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
+               }
+               if (buf + strlen(buf) >= cmdline)
+                       return -ENOSPC;
+       } else {
+               if (maxlen < sizeof(CONSOLE_ARG))
+                       return -ENOSPC;
+               strcpy(buf, CONSOLE_ARG);
+       }
+       debug("after silent fix-up: %s\n", buf);
+
+       return 0;
+}
+
+/**
+ * process_subst() - Handle substitution of ${...} fields in the environment
+ *
+ * Handle variable substitution in the provided buffer
+ *
+ * @buf: Buffer containing the string to process
+ * @maxlen: Maximum length of buffer
+ * @return 0 if OK, -ENOSPC if @maxlen is too small
+ */
+static int process_subst(char *buf, int maxlen)
+{
+       char *cmdline;
+       int size;
+       int ret;
+
+       /* Move to end of buffer */
+       size = strlen(buf) + 1;
+       cmdline = buf + maxlen - size;
+       if (buf + size > cmdline)
+               return -ENOSPC;
+       memmove(cmdline, buf, size);
+
+       ret = cli_simple_process_macros(cmdline, buf, cmdline - buf);
+
+       return ret;
+}
+
+int bootm_process_cmdline(char *buf, int maxlen, int flags)
+{
+       int ret;
+
+       /* Check config first to enable compiler to eliminate code */
+       if (IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
+           !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) &&
+           (flags & BOOTM_CL_SILENT)) {
+               ret = fixup_silent_linux(buf, maxlen);
+               if (ret)
+                       return log_msg_ret("silent", ret);
+       }
+       if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && IS_ENABLED(CONFIG_CMDLINE) &&
+           (flags & BOOTM_CL_SUBST)) {
+               ret = process_subst(buf, maxlen);
+               if (ret)
+                       return log_msg_ret("subst", ret);
+       }
+
+       return 0;
+}
+
+int bootm_process_cmdline_env(int flags)
+{
+       const int maxlen = MAX_CMDLINE_SIZE;
+       bool do_silent;
+       const char *env;
+       char *buf;
+       int ret;
+
+       /* First check if any action is needed */
+       do_silent = IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
+           !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) && (flags & BOOTM_CL_SILENT);
+       if (!do_silent && !IS_ENABLED(CONFIG_BOOTARGS_SUBST))
+               return 0;
+
+       env = env_get("bootargs");
+       if (env && strlen(env) >= maxlen)
+               return -E2BIG;
+       buf = malloc(maxlen);
+       if (!buf)
+               return -ENOMEM;
+       if (env)
+               strcpy(buf, env);
+       else
+               *buf = '\0';
+       ret = bootm_process_cmdline(buf, maxlen, flags);
+       if (!ret) {
+               ret = env_set("bootargs", buf);
+
+               /*
+                * If buf is "" and bootargs does not exist, this will produce
+                * an error trying to delete bootargs. Ignore it
+                */
+               if (ret == -ENOENT)
+                       ret = 0;
+       }
+       free(buf);
+       if (ret)
+               return log_msg_ret("env", ret);
+
+       return 0;
+}
+
+/**
+ * Execute selected states of the bootm command.
+ *
+ * Note the arguments to this state must be the first argument, Any 'bootm'
+ * or sub-command arguments must have already been taken.
+ *
+ * Note that if states contains more than one flag it MUST contain
+ * BOOTM_STATE_START, since this handles and consumes the command line args.
+ *
+ * Also note that aside from boot_os_fn functions and bootm_load_os no other
+ * functions we store the return value of in 'ret' may use a negative return
+ * value, without special handling.
+ *
+ * @param cmdtp                Pointer to bootm command table entry
+ * @param flag         Command flags (CMD_FLAG_...)
+ * @param argc         Number of subcommand arguments (0 = no arguments)
+ * @param argv         Arguments
+ * @param states       Mask containing states to run (BOOTM_STATE_...)
+ * @param images       Image header information
+ * @param boot_progress 1 to show boot progress, 0 to not do this
+ * @return 0 if ok, something else on error. Some errors will cause this
+ *     function to perform a reboot! If states contains BOOTM_STATE_OS_GO
+ *     then the intent is to boot an OS, so this function will not return
+ *     unless the image type is standalone.
+ */
+int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
+                   char *const argv[], int states, bootm_headers_t *images,
+                   int boot_progress)
+{
+       boot_os_fn *boot_fn;
+       ulong iflag = 0;
+       int ret = 0, need_boot_fn;
+
+       images->state |= states;
+
+       /*
+        * Work through the states and see how far we get. We stop on
+        * any error.
+        */
+       if (states & BOOTM_STATE_START)
+               ret = bootm_start(cmdtp, flag, argc, argv);
+
+       if (!ret && (states & BOOTM_STATE_FINDOS))
+               ret = bootm_find_os(cmdtp, flag, argc, argv);
+
+       if (!ret && (states & BOOTM_STATE_FINDOTHER))
+               ret = bootm_find_other(cmdtp, flag, argc, argv);
+
+       /* Load the OS */
+       if (!ret && (states & BOOTM_STATE_LOADOS)) {
+               iflag = bootm_disable_interrupts();
+               ret = bootm_load_os(images, 0);
+               if (ret && ret != BOOTM_ERR_OVERLAP)
+                       goto err;
+               else if (ret == BOOTM_ERR_OVERLAP)
+                       ret = 0;
+       }
+
+       /* Relocate the ramdisk */
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
+       if (!ret && (states & BOOTM_STATE_RAMDISK)) {
+               ulong rd_len = images->rd_end - images->rd_start;
+
+               ret = boot_ramdisk_high(&images->lmb, images->rd_start,
+                       rd_len, &images->initrd_start, &images->initrd_end);
+               if (!ret) {
+                       env_set_hex("initrd_start", images->initrd_start);
+                       env_set_hex("initrd_end", images->initrd_end);
+               }
+       }
+#endif
+#if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB)
+       if (!ret && (states & BOOTM_STATE_FDT)) {
+               boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
+               ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
+                                       &images->ft_len);
+       }
+#endif
+
+       /* From now on, we need the OS boot function */
+       if (ret)
+               return ret;
+       boot_fn = bootm_os_get_boot_func(images->os.os);
+       need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
+                       BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
+                       BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
+       if (boot_fn == NULL && need_boot_fn) {
+               if (iflag)
+                       enable_interrupts();
+               printf("ERROR: booting os '%s' (%d) is not supported\n",
+                      genimg_get_os_name(images->os.os), images->os.os);
+               bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
+               return 1;
+       }
+
+
+       /* Call various other states that are not generally used */
+       if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
+               ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
+       if (!ret && (states & BOOTM_STATE_OS_BD_T))
+               ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
+       if (!ret && (states & BOOTM_STATE_OS_PREP)) {
+               ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX);
+               if (ret) {
+                       printf("Cmdline setup failed (err=%d)\n", ret);
+                       ret = CMD_RET_FAILURE;
+                       goto err;
+               }
+               ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
+       }
+
+#ifdef CONFIG_TRACE
+       /* Pretend to run the OS, then run a user command */
+       if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
+               char *cmd_list = env_get("fakegocmd");
+
+               ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
+                               images, boot_fn);
+               if (!ret && cmd_list)
+                       ret = run_command_list(cmd_list, -1, flag);
+       }
+#endif
+
+       /* Check for unsupported subcommand. */
+       if (ret) {
+               puts("subcommand not supported\n");
+               return ret;
+       }
+
+       /* Now run the OS! We hope this doesn't return */
+       if (!ret && (states & BOOTM_STATE_OS_GO))
+               ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
+                               images, boot_fn);
+
+       /* Deal with any fallout */
+err:
+       if (iflag)
+               enable_interrupts();
+
+       if (ret == BOOTM_ERR_UNIMPLEMENTED)
+               bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
+       else if (ret == BOOTM_ERR_RESET)
+               do_reset(cmdtp, flag, argc, argv);
+
+       return ret;
+}
+
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
+/**
+ * image_get_kernel - verify legacy format kernel image
+ * @img_addr: in RAM address of the legacy format image to be verified
+ * @verify: data CRC verification flag
+ *
+ * image_get_kernel() verifies legacy image integrity and returns pointer to
+ * legacy image header if image verification was completed successfully.
+ *
+ * returns:
+ *     pointer to a legacy image header if valid image was found
+ *     otherwise return NULL
+ */
+static image_header_t *image_get_kernel(ulong img_addr, int verify)
+{
+       image_header_t *hdr = (image_header_t *)img_addr;
+
+       if (!image_check_magic(hdr)) {
+               puts("Bad Magic Number\n");
+               bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
+               return NULL;
+       }
+       bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
+
+       if (!image_check_hcrc(hdr)) {
+               puts("Bad Header Checksum\n");
+               bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
+               return NULL;
+       }
+
+       bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
+       image_print_contents(hdr);
+
+       if (verify) {
+               puts("   Verifying Checksum ... ");
+               if (!image_check_dcrc(hdr)) {
+                       printf("Bad Data CRC\n");
+                       bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
+                       return NULL;
+               }
+               puts("OK\n");
+       }
+       bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
+
+       if (!image_check_target_arch(hdr)) {
+               printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
+               bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
+               return NULL;
+       }
+       return hdr;
+}
+#endif
+
+/**
+ * boot_get_kernel - find kernel image
+ * @os_data: pointer to a ulong variable, will hold os data start address
+ * @os_len: pointer to a ulong variable, will hold os data length
+ *
+ * boot_get_kernel() tries to find a kernel image, verifies its integrity
+ * and locates kernel data.
+ *
+ * returns:
+ *     pointer to image header if valid image was found, plus kernel start
+ *     address and length, otherwise NULL
+ */
+static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
+                                  char *const argv[], bootm_headers_t *images,
+                                  ulong *os_data, ulong *os_len)
+{
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
+       image_header_t  *hdr;
+#endif
+       ulong           img_addr;
+       const void *buf;
+       const char      *fit_uname_config = NULL;
+       const char      *fit_uname_kernel = NULL;
+#if CONFIG_IS_ENABLED(FIT)
+       int             os_noffset;
+#endif
+
+       img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
+                                             &fit_uname_config,
+                                             &fit_uname_kernel);
+
+       bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
+
+       /* check image type, for FIT images get FIT kernel node */
+       *os_data = *os_len = 0;
+       buf = map_sysmem(img_addr, 0);
+       switch (genimg_get_format(buf)) {
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
+       case IMAGE_FORMAT_LEGACY:
+               printf("## Booting kernel from Legacy Image at %08lx ...\n",
+                      img_addr);
+               hdr = image_get_kernel(img_addr, images->verify);
+               if (!hdr)
+                       return NULL;
+               bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
+
+               /* get os_data and os_len */
+               switch (image_get_type(hdr)) {
+               case IH_TYPE_KERNEL:
+               case IH_TYPE_KERNEL_NOLOAD:
+                       *os_data = image_get_data(hdr);
+                       *os_len = image_get_data_size(hdr);
+                       break;
+               case IH_TYPE_MULTI:
+                       image_multi_getimg(hdr, 0, os_data, os_len);
+                       break;
+               case IH_TYPE_STANDALONE:
+                       *os_data = image_get_data(hdr);
+                       *os_len = image_get_data_size(hdr);
+                       break;
+               default:
+                       printf("Wrong Image Type for %s command\n",
+                              cmdtp->name);
+                       bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
+                       return NULL;
+               }
+
+               /*
+                * copy image header to allow for image overwrites during
+                * kernel decompression.
+                */
+               memmove(&images->legacy_hdr_os_copy, hdr,
+                       sizeof(image_header_t));
+
+               /* save pointer to image header */
+               images->legacy_hdr_os = hdr;
+
+               images->legacy_hdr_valid = 1;
+               bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
+               break;
+#endif
+#if CONFIG_IS_ENABLED(FIT)
+       case IMAGE_FORMAT_FIT:
+               os_noffset = fit_image_load(images, img_addr,
+                               &fit_uname_kernel, &fit_uname_config,
+                               IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
+                               BOOTSTAGE_ID_FIT_KERNEL_START,
+                               FIT_LOAD_IGNORED, os_data, os_len);
+               if (os_noffset < 0)
+                       return NULL;
+
+               images->fit_hdr_os = map_sysmem(img_addr, 0);
+               images->fit_uname_os = fit_uname_kernel;
+               images->fit_uname_cfg = fit_uname_config;
+               images->fit_noffset_os = os_noffset;
+               break;
+#endif
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+       case IMAGE_FORMAT_ANDROID:
+               printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
+               if (android_image_get_kernel(buf, images->verify,
+                                            os_data, os_len))
+                       return NULL;
+               break;
+#endif
+       default:
+               printf("Wrong Image Format for %s command\n", cmdtp->name);
+               bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
+               return NULL;
+       }
+
+       debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
+             *os_data, *os_len, *os_len);
+
+       return buf;
+}
+
+/**
+ * switch_to_non_secure_mode() - switch to non-secure mode
+ *
+ * This routine is overridden by architectures requiring this feature.
+ */
+void __weak switch_to_non_secure_mode(void)
+{
+}
+
+#else /* USE_HOSTCC */
+
+#if defined(CONFIG_FIT_SIGNATURE)
+static int bootm_host_load_image(const void *fit, int req_image_type,
+                                int cfg_noffset)
+{
+       const char *fit_uname_config = NULL;
+       ulong data, len;
+       bootm_headers_t images;
+       int noffset;
+       ulong load_end;
+       uint8_t image_type;
+       uint8_t imape_comp;
+       void *load_buf;
+       int ret;
+
+       fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
+       memset(&images, '\0', sizeof(images));
+       images.verify = 1;
+       noffset = fit_image_load(&images, (ulong)fit,
+               NULL, &fit_uname_config,
+               IH_ARCH_DEFAULT, req_image_type, -1,
+               FIT_LOAD_IGNORED, &data, &len);
+       if (noffset < 0)
+               return noffset;
+       if (fit_image_get_type(fit, noffset, &image_type)) {
+               puts("Can't get image type!\n");
+               return -EINVAL;
+       }
+
+       if (fit_image_get_comp(fit, noffset, &imape_comp)) {
+               puts("Can't get image compression!\n");
+               return -EINVAL;
+       }
+
+       /* Allow the image to expand by a factor of 4, should be safe */
+       load_buf = malloc((1 << 20) + len * 4);
+       ret = image_decomp(imape_comp, 0, data, image_type, load_buf,
+                          (void *)data, len, CONFIG_SYS_BOOTM_LEN,
+                          &load_end);
+       free(load_buf);
+
+       if (ret) {
+               ret = handle_decomp_error(imape_comp, load_end - 0, ret);
+               if (ret != BOOTM_ERR_UNIMPLEMENTED)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int bootm_host_load_images(const void *fit, int cfg_noffset)
+{
+       static uint8_t image_types[] = {
+               IH_TYPE_KERNEL,
+               IH_TYPE_FLATDT,
+               IH_TYPE_RAMDISK,
+       };
+       int err = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(image_types); i++) {
+               int ret;
+
+               ret = bootm_host_load_image(fit, image_types[i], cfg_noffset);
+               if (!err && ret && ret != -ENOENT)
+                       err = ret;
+       }
+
+       /* Return the first error we found */
+       return err;
+}
+#endif
+
+#endif /* ndef USE_HOSTCC */
diff --git a/boot/bootm_os.c b/boot/bootm_os.c
new file mode 100644 (file)
index 0000000..39623f9
--- /dev/null
@@ -0,0 +1,653 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2009
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <bootm.h>
+#include <bootstage.h>
+#include <cpu_func.h>
+#include <efi_loader.h>
+#include <env.h>
+#include <fdt_support.h>
+#include <image.h>
+#include <lmb.h>
+#include <log.h>
+#include <asm/global_data.h>
+#include <linux/libfdt.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <vxworks.h>
+#include <tee/optee.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int do_bootm_standalone(int flag, int argc, char *const argv[],
+                              bootm_headers_t *images)
+{
+       char *s;
+       int (*appl)(int, char *const[]);
+
+       /* Don't start if "autostart" is set to "no" */
+       s = env_get("autostart");
+       if ((s != NULL) && !strcmp(s, "no")) {
+               env_set_hex("filesize", images->os.image_len);
+               return 0;
+       }
+       appl = (int (*)(int, char * const []))images->ep;
+       appl(argc, argv);
+       return 0;
+}
+
+/*******************************************************************/
+/* OS booting routines */
+/*******************************************************************/
+
+#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
+static void copy_args(char *dest, int argc, char *const argv[], char delim)
+{
+       int i;
+
+       for (i = 0; i < argc; i++) {
+               if (i > 0)
+                       *dest++ = delim;
+               strcpy(dest, argv[i]);
+               dest += strlen(argv[i]);
+       }
+}
+#endif
+
+static void __maybe_unused fit_unsupported_reset(const char *msg)
+{
+       if (CONFIG_IS_ENABLED(FIT_VERBOSE)) {
+               printf("! FIT images not supported for '%s' - must reset board to recover!\n",
+                      msg);
+       }
+}
+
+#ifdef CONFIG_BOOTM_NETBSD
+static int do_bootm_netbsd(int flag, int argc, char *const argv[],
+                          bootm_headers_t *images)
+{
+       void (*loader)(struct bd_info *, image_header_t *, char *, char *);
+       image_header_t *os_hdr, *hdr;
+       ulong kernel_data, kernel_len;
+       char *cmdline;
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("NetBSD");
+               return 1;
+       }
+#endif
+       hdr = images->legacy_hdr_os;
+
+       /*
+        * Booting a (NetBSD) kernel image
+        *
+        * This process is pretty similar to a standalone application:
+        * The (first part of an multi-) image must be a stage-2 loader,
+        * which in turn is responsible for loading & invoking the actual
+        * kernel.  The only differences are the parameters being passed:
+        * besides the board info strucure, the loader expects a command
+        * line, the name of the console device, and (optionally) the
+        * address of the original image header.
+        */
+       os_hdr = NULL;
+       if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
+               image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
+               if (kernel_len)
+                       os_hdr = hdr;
+       }
+
+       if (argc > 0) {
+               ulong len;
+               int   i;
+
+               for (i = 0, len = 0; i < argc; i += 1)
+                       len += strlen(argv[i]) + 1;
+               cmdline = malloc(len);
+               copy_args(cmdline, argc, argv, ' ');
+       } else {
+               cmdline = env_get("bootargs");
+               if (cmdline == NULL)
+                       cmdline = "";
+       }
+
+       loader = (void (*)(struct bd_info *, image_header_t *, char *, char *))images->ep;
+
+       printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
+              (ulong)loader);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * NetBSD Stage-2 Loader Parameters:
+        *   arg[0]: pointer to board info data
+        *   arg[1]: image load address
+        *   arg[2]: char pointer to the console device to use
+        *   arg[3]: char pointer to the boot arguments
+        */
+       (*loader)(gd->bd, os_hdr, "", cmdline);
+
+       return 1;
+}
+#endif /* CONFIG_BOOTM_NETBSD*/
+
+#ifdef CONFIG_LYNXKDI
+static int do_bootm_lynxkdi(int flag, int argc, char *const argv[],
+                           bootm_headers_t *images)
+{
+       image_header_t *hdr = &images->legacy_hdr_os_copy;
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("Lynx");
+               return 1;
+       }
+#endif
+
+       lynxkdi_boot((image_header_t *)hdr);
+
+       return 1;
+}
+#endif /* CONFIG_LYNXKDI */
+
+#ifdef CONFIG_BOOTM_RTEMS
+static int do_bootm_rtems(int flag, int argc, char *const argv[],
+                         bootm_headers_t *images)
+{
+       void (*entry_point)(struct bd_info *);
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("RTEMS");
+               return 1;
+       }
+#endif
+
+       entry_point = (void (*)(struct bd_info *))images->ep;
+
+       printf("## Transferring control to RTEMS (at address %08lx) ...\n",
+              (ulong)entry_point);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * RTEMS Parameters:
+        *   r3: ptr to board info data
+        */
+       (*entry_point)(gd->bd);
+
+       return 1;
+}
+#endif /* CONFIG_BOOTM_RTEMS */
+
+#if defined(CONFIG_BOOTM_OSE)
+static int do_bootm_ose(int flag, int argc, char *const argv[],
+                       bootm_headers_t *images)
+{
+       void (*entry_point)(void);
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("OSE");
+               return 1;
+       }
+#endif
+
+       entry_point = (void (*)(void))images->ep;
+
+       printf("## Transferring control to OSE (at address %08lx) ...\n",
+              (ulong)entry_point);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * OSE Parameters:
+        *   None
+        */
+       (*entry_point)();
+
+       return 1;
+}
+#endif /* CONFIG_BOOTM_OSE */
+
+#if defined(CONFIG_BOOTM_PLAN9)
+static int do_bootm_plan9(int flag, int argc, char *const argv[],
+                         bootm_headers_t *images)
+{
+       void (*entry_point)(void);
+       char *s;
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("Plan 9");
+               return 1;
+       }
+#endif
+
+       /* See README.plan9 */
+       s = env_get("confaddr");
+       if (s != NULL) {
+               char *confaddr = (char *)hextoul(s, NULL);
+
+               if (argc > 0) {
+                       copy_args(confaddr, argc, argv, '\n');
+               } else {
+                       s = env_get("bootargs");
+                       if (s != NULL)
+                               strcpy(confaddr, s);
+               }
+       }
+
+       entry_point = (void (*)(void))images->ep;
+
+       printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
+              (ulong)entry_point);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * Plan 9 Parameters:
+        *   None
+        */
+       (*entry_point)();
+
+       return 1;
+}
+#endif /* CONFIG_BOOTM_PLAN9 */
+
+#if defined(CONFIG_BOOTM_VXWORKS) && \
+       (defined(CONFIG_PPC) || defined(CONFIG_ARM))
+
+static void do_bootvx_fdt(bootm_headers_t *images)
+{
+#if defined(CONFIG_OF_LIBFDT)
+       int ret;
+       char *bootline;
+       ulong of_size = images->ft_len;
+       char **of_flat_tree = &images->ft_addr;
+       struct lmb *lmb = &images->lmb;
+
+       if (*of_flat_tree) {
+               boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+
+               ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
+               if (ret)
+                       return;
+
+               /* Update ethernet nodes */
+               fdt_fixup_ethernet(*of_flat_tree);
+
+               ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
+               if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
+                       bootline = env_get("bootargs");
+                       if (bootline) {
+                               ret = fdt_find_and_setprop(*of_flat_tree,
+                                               "/chosen", "bootargs",
+                                               bootline,
+                                               strlen(bootline) + 1, 1);
+                               if (ret < 0) {
+                                       printf("## ERROR: %s : %s\n", __func__,
+                                              fdt_strerror(ret));
+                                       return;
+                               }
+                       }
+               } else {
+                       printf("## ERROR: %s : %s\n", __func__,
+                              fdt_strerror(ret));
+                       return;
+               }
+       }
+#endif
+
+       boot_prep_vxworks(images);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+#if defined(CONFIG_OF_LIBFDT)
+       printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
+              (ulong)images->ep, (ulong)*of_flat_tree);
+#else
+       printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
+#endif
+
+       boot_jump_vxworks(images);
+
+       puts("## vxWorks terminated\n");
+}
+
+static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[],
+                                  bootm_headers_t *images)
+{
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("VxWorks");
+               return 1;
+       }
+#endif
+
+       do_bootvx_fdt(images);
+
+       return 1;
+}
+
+int do_bootm_vxworks(int flag, int argc, char *const argv[],
+                    bootm_headers_t *images)
+{
+       char *bootargs;
+       int pos;
+       unsigned long vxflags;
+       bool std_dtb = false;
+
+       /* get bootargs env */
+       bootargs = env_get("bootargs");
+
+       if (bootargs != NULL) {
+               for (pos = 0; pos < strlen(bootargs); pos++) {
+                       /* find f=0xnumber flag */
+                       if ((bootargs[pos] == '=') && (pos >= 1) &&
+                           (bootargs[pos - 1] == 'f')) {
+                               vxflags = hextoul(&bootargs[pos + 1], NULL);
+                               if (vxflags & VXWORKS_SYSFLG_STD_DTB)
+                                       std_dtb = true;
+                       }
+               }
+       }
+
+       if (std_dtb) {
+               if (flag & BOOTM_STATE_OS_PREP)
+                       printf("   Using standard DTB\n");
+               return do_bootm_linux(flag, argc, argv, images);
+       } else {
+               if (flag & BOOTM_STATE_OS_PREP)
+                       printf("   !!! WARNING !!! Using legacy DTB\n");
+               return do_bootm_vxworks_legacy(flag, argc, argv, images);
+       }
+}
+#endif
+
+#if defined(CONFIG_CMD_ELF)
+static int do_bootm_qnxelf(int flag, int argc, char *const argv[],
+                          bootm_headers_t *images)
+{
+       char *local_args[2];
+       char str[16];
+       int dcache;
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("QNX");
+               return 1;
+       }
+#endif
+
+       sprintf(str, "%lx", images->ep); /* write entry-point into string */
+       local_args[0] = argv[0];
+       local_args[1] = str;    /* and provide it via the arguments */
+
+       /*
+        * QNX images require the data cache is disabled.
+        */
+       dcache = dcache_status();
+       if (dcache)
+               dcache_disable();
+
+       do_bootelf(NULL, 0, 2, local_args);
+
+       if (dcache)
+               dcache_enable();
+
+       return 1;
+}
+#endif
+
+#ifdef CONFIG_INTEGRITY
+static int do_bootm_integrity(int flag, int argc, char *const argv[],
+                             bootm_headers_t *images)
+{
+       void (*entry_point)(void);
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("INTEGRITY");
+               return 1;
+       }
+#endif
+
+       entry_point = (void (*)(void))images->ep;
+
+       printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
+              (ulong)entry_point);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * INTEGRITY Parameters:
+        *   None
+        */
+       (*entry_point)();
+
+       return 1;
+}
+#endif
+
+#ifdef CONFIG_BOOTM_OPENRTOS
+static int do_bootm_openrtos(int flag, int argc, char *const argv[],
+                            bootm_headers_t *images)
+{
+       void (*entry_point)(void);
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+       entry_point = (void (*)(void))images->ep;
+
+       printf("## Transferring control to OpenRTOS (at address %08lx) ...\n",
+               (ulong)entry_point);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * OpenRTOS Parameters:
+        *   None
+        */
+       (*entry_point)();
+
+       return 1;
+}
+#endif
+
+#ifdef CONFIG_BOOTM_OPTEE
+static int do_bootm_tee(int flag, int argc, char *const argv[],
+                       bootm_headers_t *images)
+{
+       int ret;
+
+       /* Verify OS type */
+       if (images->os.os != IH_OS_TEE) {
+               return 1;
+       };
+
+       /* Validate OPTEE header */
+       ret = optee_verify_bootm_image(images->os.image_start,
+                                      images->os.load,
+                                      images->os.image_len);
+       if (ret)
+               return ret;
+
+       /* Locate FDT etc */
+       ret = bootm_find_images(flag, argc, argv, 0, 0);
+       if (ret)
+               return ret;
+
+       /* From here we can run the regular linux boot path */
+       return do_bootm_linux(flag, argc, argv, images);
+}
+#endif
+
+#ifdef CONFIG_BOOTM_EFI
+static int do_bootm_efi(int flag, int argc, char *const argv[],
+                       bootm_headers_t *images)
+{
+       int ret;
+       efi_status_t efi_ret;
+       void *image_buf;
+
+       if (flag != BOOTM_STATE_OS_GO)
+               return 0;
+
+       /* Locate FDT, if provided */
+       ret = bootm_find_images(flag, argc, argv, 0, 0);
+       if (ret)
+               return ret;
+
+       /* Initialize EFI drivers */
+       efi_ret = efi_init_obj_list();
+       if (efi_ret != EFI_SUCCESS) {
+               printf("## Failed to initialize UEFI sub-system: r = %lu\n",
+                      efi_ret & ~EFI_ERROR_MASK);
+               return 1;
+       }
+
+       /* Install device tree */
+       efi_ret = efi_install_fdt(images->ft_len
+                                 ? images->ft_addr : EFI_FDT_USE_INTERNAL);
+       if (efi_ret != EFI_SUCCESS) {
+               printf("## Failed to install device tree: r = %lu\n",
+                      efi_ret & ~EFI_ERROR_MASK);
+               return 1;
+       }
+
+       /* Run EFI image */
+       printf("## Transferring control to EFI (at address %08lx) ...\n",
+              images->ep);
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /* We expect to return */
+       images->os.type = IH_TYPE_STANDALONE;
+
+       image_buf = map_sysmem(images->ep, images->os.image_len);
+
+       efi_ret = efi_run_image(image_buf, images->os.image_len);
+       if (efi_ret != EFI_SUCCESS)
+               return 1;
+       return 0;
+}
+#endif
+
+static boot_os_fn *boot_os[] = {
+       [IH_OS_U_BOOT] = do_bootm_standalone,
+#ifdef CONFIG_BOOTM_LINUX
+       [IH_OS_LINUX] = do_bootm_linux,
+#endif
+#ifdef CONFIG_BOOTM_NETBSD
+       [IH_OS_NETBSD] = do_bootm_netbsd,
+#endif
+#ifdef CONFIG_LYNXKDI
+       [IH_OS_LYNXOS] = do_bootm_lynxkdi,
+#endif
+#ifdef CONFIG_BOOTM_RTEMS
+       [IH_OS_RTEMS] = do_bootm_rtems,
+#endif
+#if defined(CONFIG_BOOTM_OSE)
+       [IH_OS_OSE] = do_bootm_ose,
+#endif
+#if defined(CONFIG_BOOTM_PLAN9)
+       [IH_OS_PLAN9] = do_bootm_plan9,
+#endif
+#if defined(CONFIG_BOOTM_VXWORKS) && \
+       (defined(CONFIG_PPC) || defined(CONFIG_ARM) || defined(CONFIG_RISCV))
+       [IH_OS_VXWORKS] = do_bootm_vxworks,
+#endif
+#if defined(CONFIG_CMD_ELF)
+       [IH_OS_QNX] = do_bootm_qnxelf,
+#endif
+#ifdef CONFIG_INTEGRITY
+       [IH_OS_INTEGRITY] = do_bootm_integrity,
+#endif
+#ifdef CONFIG_BOOTM_OPENRTOS
+       [IH_OS_OPENRTOS] = do_bootm_openrtos,
+#endif
+#ifdef CONFIG_BOOTM_OPTEE
+       [IH_OS_TEE] = do_bootm_tee,
+#endif
+#ifdef CONFIG_BOOTM_EFI
+       [IH_OS_EFI] = do_bootm_efi,
+#endif
+};
+
+/* Allow for arch specific config before we boot */
+__weak void arch_preboot_os(void)
+{
+       /* please define platform specific arch_preboot_os() */
+}
+
+/* Allow for board specific config before we boot */
+__weak void board_preboot_os(void)
+{
+       /* please define board specific board_preboot_os() */
+}
+
+int boot_selected_os(int argc, char *const argv[], int state,
+                    bootm_headers_t *images, boot_os_fn *boot_fn)
+{
+       arch_preboot_os();
+       board_preboot_os();
+       boot_fn(state, argc, argv, images);
+
+       /* Stand-alone may return when 'autostart' is 'no' */
+       if (images->os.type == IH_TYPE_STANDALONE ||
+           IS_ENABLED(CONFIG_SANDBOX) ||
+           state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
+               return 0;
+       bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
+       debug("\n## Control returned to monitor - resetting...\n");
+
+       return BOOTM_ERR_RESET;
+}
+
+boot_os_fn *bootm_os_get_boot_func(int os)
+{
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+       static bool relocated;
+
+       if (!relocated) {
+               int i;
+
+               /* relocate boot function table */
+               for (i = 0; i < ARRAY_SIZE(boot_os); i++)
+                       if (boot_os[i] != NULL)
+                               boot_os[i] += gd->reloc_off;
+
+               relocated = true;
+       }
+#endif
+       return boot_os[os];
+}
diff --git a/boot/bootretry.c b/boot/bootretry.c
new file mode 100644 (file)
index 0000000..dac891f
--- /dev/null
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <bootretry.h>
+#include <cli.h>
+#include <env.h>
+#include <errno.h>
+#include <time.h>
+#include <watchdog.h>
+
+#ifndef CONFIG_BOOT_RETRY_MIN
+#define CONFIG_BOOT_RETRY_MIN CONFIG_BOOT_RETRY_TIME
+#endif
+
+static uint64_t endtime;  /* must be set, default is instant timeout */
+static int      retry_time = -1; /* -1 so can call readline before main_loop */
+
+/***************************************************************************
+ * initialize command line timeout
+ */
+void bootretry_init_cmd_timeout(void)
+{
+       char *s = env_get("bootretry");
+
+       if (s != NULL)
+               retry_time = (int)simple_strtol(s, NULL, 10);
+       else
+               retry_time = CONFIG_BOOT_RETRY_TIME;
+
+       if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
+               retry_time = CONFIG_BOOT_RETRY_MIN;
+}
+
+/***************************************************************************
+ * reset command line timeout to retry_time seconds
+ */
+void bootretry_reset_cmd_timeout(void)
+{
+       endtime = endtick(retry_time);
+}
+
+int bootretry_tstc_timeout(void)
+{
+       while (!tstc()) {       /* while no incoming data */
+               if (retry_time >= 0 && get_ticks() > endtime)
+                       return -ETIMEDOUT;
+               WATCHDOG_RESET();
+       }
+
+       return 0;
+}
+
+void bootretry_dont_retry(void)
+{
+       retry_time = -1;
+}
diff --git a/boot/common_fit.c b/boot/common_fit.c
new file mode 100644 (file)
index 0000000..cde2dc4
--- /dev/null
@@ -0,0 +1,86 @@
+// 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 <image.h>
+#include <log.h>
+#include <linux/libfdt.h>
+
+ulong fdt_getprop_u32(const void *fdt, int node, const char *prop)
+{
+       const u32 *cell;
+       int len;
+
+       cell = fdt_getprop(fdt, node, prop, &len);
+       if (!cell || len != sizeof(*cell))
+               return FDT_ERROR;
+
+       return fdt32_to_cpu(*cell);
+}
+
+__weak int board_fit_config_name_match(const char *name)
+{
+       return -EINVAL;
+}
+
+/*
+ * Iterate over all /configurations subnodes and call a platform specific
+ * function to find the matching configuration.
+ * Returns the node offset or a negative error number.
+ */
+int fit_find_config_node(const void *fdt)
+{
+       const char *name;
+       int conf, node, len;
+       const char *dflt_conf_name;
+       const char *dflt_conf_desc = NULL;
+       int dflt_conf_node = -ENOENT;
+
+       conf = fdt_path_offset(fdt, FIT_CONFS_PATH);
+       if (conf < 0) {
+               debug("%s: Cannot find /configurations node: %d\n", __func__,
+                     conf);
+               return -EINVAL;
+       }
+
+       dflt_conf_name = fdt_getprop(fdt, conf, "default", &len);
+
+       for (node = fdt_first_subnode(fdt, conf);
+            node >= 0;
+            node = fdt_next_subnode(fdt, node)) {
+               name = fdt_getprop(fdt, node, "description", &len);
+               if (!name) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+                       printf("%s: Missing FDT description in DTB\n",
+                              __func__);
+#endif
+                       return -EINVAL;
+               }
+
+               if (dflt_conf_name) {
+                       const char *node_name = fdt_get_name(fdt, node, NULL);
+                       if (strcmp(dflt_conf_name, node_name) == 0) {
+                               dflt_conf_node = node;
+                               dflt_conf_desc = name;
+                       }
+               }
+
+               if (board_fit_config_name_match(name))
+                       continue;
+
+               debug("Selecting config '%s'\n", name);
+
+               return node;
+       }
+
+       if (dflt_conf_node != -ENOENT) {
+               debug("Selecting default config '%s'\n", dflt_conf_desc);
+               return dflt_conf_node;
+       }
+
+       return -ENOENT;
+}
diff --git a/boot/fdt_region.c b/boot/fdt_region.c
new file mode 100644 (file)
index 0000000..e4ef0ca
--- /dev/null
@@ -0,0 +1,671 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2013 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <fdt_support.h>
+#include <linux/libfdt_env.h>
+#include <fdt_region.h>
+
+#ifndef USE_HOSTCC
+#include <fdt.h>
+#include <linux/libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
+
+#define FDT_MAX_DEPTH  32
+
+static int str_in_list(const char *str, char * const list[], int count)
+{
+       int i;
+
+       for (i = 0; i < count; i++)
+               if (!strcmp(list[i], str))
+                       return 1;
+
+       return 0;
+}
+
+int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
+                    char * const exc_prop[], int exc_prop_count,
+                    struct fdt_region region[], int max_regions,
+                    char *path, int path_len, int add_string_tab)
+{
+       int stack[FDT_MAX_DEPTH] = { 0 };
+       char *end;
+       int nextoffset = 0;
+       uint32_t tag;
+       int count = 0;
+       int start = -1;
+       int depth = -1;
+       int want = 0;
+       int base = fdt_off_dt_struct(fdt);
+       bool expect_end = false;
+
+       end = path;
+       *end = '\0';
+       do {
+               const struct fdt_property *prop;
+               const char *name;
+               const char *str;
+               int include = 0;
+               int stop_at = 0;
+               int offset;
+               int len;
+
+               offset = nextoffset;
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
+               stop_at = nextoffset;
+
+               /* If we see two root nodes, something is wrong */
+               if (expect_end && tag != FDT_END)
+                       return -FDT_ERR_BADLAYOUT;
+
+               switch (tag) {
+               case FDT_PROP:
+                       include = want >= 2;
+                       stop_at = offset;
+                       prop = fdt_get_property_by_offset(fdt, offset, NULL);
+                       str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+                       if (!str)
+                               return -FDT_ERR_BADSTRUCTURE;
+                       if (str_in_list(str, exc_prop, exc_prop_count))
+                               include = 0;
+                       break;
+
+               case FDT_NOP:
+                       include = want >= 2;
+                       stop_at = offset;
+                       break;
+
+               case FDT_BEGIN_NODE:
+                       depth++;
+                       if (depth == FDT_MAX_DEPTH)
+                               return -FDT_ERR_BADSTRUCTURE;
+                       name = fdt_get_name(fdt, offset, &len);
+
+                       /* The root node must have an empty name */
+                       if (!depth && *name)
+                               return -FDT_ERR_BADLAYOUT;
+                       if (end - path + 2 + len >= path_len)
+                               return -FDT_ERR_NOSPACE;
+                       if (end != path + 1)
+                               *end++ = '/';
+                       strcpy(end, name);
+                       end += len;
+                       stack[depth] = want;
+                       if (want == 1)
+                               stop_at = offset;
+                       if (str_in_list(path, inc, inc_count))
+                               want = 2;
+                       else if (want)
+                               want--;
+                       else
+                               stop_at = offset;
+                       include = want;
+                       break;
+
+               case FDT_END_NODE:
+                       /* Depth must never go below -1 */
+                       if (depth < 0)
+                               return -FDT_ERR_BADSTRUCTURE;
+                       include = want;
+                       want = stack[depth--];
+                       while (end > path && *--end != '/')
+                               ;
+                       *end = '\0';
+                       if (depth == -1)
+                               expect_end = true;
+                       break;
+
+               case FDT_END:
+                       include = 1;
+                       break;
+               }
+
+               if (include && start == -1) {
+                       /* Should we merge with previous? */
+                       if (count && count <= max_regions &&
+                           offset == region[count - 1].offset +
+                                       region[count - 1].size - base)
+                               start = region[--count].offset - base;
+                       else
+                               start = offset;
+               }
+
+               if (!include && start != -1) {
+                       if (count < max_regions) {
+                               region[count].offset = base + start;
+                               region[count].size = stop_at - start;
+                       }
+                       count++;
+                       start = -1;
+               }
+       } while (tag != FDT_END);
+
+       if (nextoffset != fdt_size_dt_struct(fdt))
+               return -FDT_ERR_BADLAYOUT;
+
+       /* Add a region for the END tag and the string table */
+       if (count < max_regions) {
+               region[count].offset = base + start;
+               region[count].size = nextoffset - start;
+               if (add_string_tab)
+                       region[count].size += fdt_size_dt_strings(fdt);
+       }
+       count++;
+
+       return count;
+}
+
+/**
+ * fdt_add_region() - Add a new region to our list
+ * @info:      State information
+ * @offset:    Start offset of region
+ * @size:      Size of region
+ *
+ * The region is added if there is space, but in any case we increment the
+ * count. If permitted, and the new region overlaps the last one, we merge
+ * them.
+ */
+static int fdt_add_region(struct fdt_region_state *info, int offset, int size)
+{
+       struct fdt_region *reg;
+
+       reg = info->region ? &info->region[info->count - 1] : NULL;
+       if (info->can_merge && info->count &&
+           info->count <= info->max_regions &&
+           reg && offset <= reg->offset + reg->size) {
+               reg->size = offset + size - reg->offset;
+       } else if (info->count++ < info->max_regions) {
+               if (reg) {
+                       reg++;
+                       reg->offset = offset;
+                       reg->size = size;
+               }
+       } else {
+               return -1;
+       }
+
+       return 0;
+}
+
+static int region_list_contains_offset(struct fdt_region_state *info,
+                                      const void *fdt, int target)
+{
+       struct fdt_region *reg;
+       int num;
+
+       target += fdt_off_dt_struct(fdt);
+       for (reg = info->region, num = 0; num < info->count; reg++, num++) {
+               if (target >= reg->offset && target < reg->offset + reg->size)
+                       return 1;
+       }
+
+       return 0;
+}
+
+/**
+ * fdt_add_alias_regions() - Add regions covering the aliases that we want
+ *
+ * The /aliases node is not automatically included by fdtgrep unless the
+ * command-line arguments cause to be included (or not excluded). However
+ * aliases are special in that we generally want to include those which
+ * reference a node that fdtgrep includes.
+ *
+ * In fact we want to include only aliases for those nodes still included in
+ * the fdt, and drop the other aliases since they point to nodes that will not
+ * be present.
+ *
+ * This function scans the aliases and adds regions for those which we want
+ * to keep.
+ *
+ * @fdt: Device tree to scan
+ * @region: List of regions
+ * @count: Number of regions in the list so far (i.e. starting point for this
+ *     function)
+ * @max_regions: Maximum number of regions in @region list
+ * @info: Place to put the region state
+ * @return number of regions after processing, or -FDT_ERR_NOSPACE if we did
+ * not have enough room in the regions table for the regions we wanted to add.
+ */
+int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count,
+                         int max_regions, struct fdt_region_state *info)
+{
+       int base = fdt_off_dt_struct(fdt);
+       int node, node_end, offset;
+       int did_alias_header;
+
+       node = fdt_subnode_offset(fdt, 0, "aliases");
+       if (node < 0)
+               return -FDT_ERR_NOTFOUND;
+
+       /*
+        * Find the next node so that we know where the /aliases node ends. We
+        * need special handling if /aliases is the last node.
+        */
+       node_end = fdt_next_subnode(fdt, node);
+       if (node_end == -FDT_ERR_NOTFOUND)
+               /* Move back to the FDT_END_NODE tag of '/' */
+               node_end = fdt_size_dt_struct(fdt) - sizeof(fdt32_t) * 2;
+       else if (node_end < 0) /* other error */
+               return node_end;
+       node_end -= sizeof(fdt32_t);  /* Move to FDT_END_NODE tag of /aliases */
+
+       did_alias_header = 0;
+       info->region = region;
+       info->count = count;
+       info->can_merge = 0;
+       info->max_regions = max_regions;
+
+       for (offset = fdt_first_property_offset(fdt, node);
+            offset >= 0;
+            offset = fdt_next_property_offset(fdt, offset)) {
+               const struct fdt_property *prop;
+               const char *name;
+               int target, next;
+
+               prop = fdt_get_property_by_offset(fdt, offset, NULL);
+               name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+               target = fdt_path_offset(fdt, name);
+               if (!region_list_contains_offset(info, fdt, target))
+                       continue;
+               next = fdt_next_property_offset(fdt, offset);
+               if (next < 0)
+                       next = node_end;
+
+               if (!did_alias_header) {
+                       fdt_add_region(info, base + node, 12);
+                       did_alias_header = 1;
+               }
+               fdt_add_region(info, base + offset, next - offset);
+       }
+
+       /* Add the FDT_END_NODE tag */
+       if (did_alias_header)
+               fdt_add_region(info, base + node_end, sizeof(fdt32_t));
+
+       return info->count < max_regions ? info->count : -FDT_ERR_NOSPACE;
+}
+
+/**
+ * fdt_include_supernodes() - Include supernodes required by this node
+ * @info:      State information
+ * @depth:     Current stack depth
+ *
+ * When we decided to include a node or property which is not at the top
+ * level, this function forces the inclusion of higher level nodes. For
+ * example, given this tree:
+ *
+ * / {
+ *     testing {
+ *     }
+ * }
+ *
+ * If we decide to include testing then we need the root node to have a valid
+ * tree. This function adds those regions.
+ */
+static int fdt_include_supernodes(struct fdt_region_state *info, int depth)
+{
+       int base = fdt_off_dt_struct(info->fdt);
+       int start, stop_at;
+       int i;
+
+       /*
+        * Work down the stack looking for supernodes that we didn't include.
+        * The algortihm here is actually pretty simple, since we know that
+        * no previous subnode had to include these nodes, or if it did, we
+        * marked them as included (on the stack) already.
+        */
+       for (i = 0; i <= depth; i++) {
+               if (!info->stack[i].included) {
+                       start = info->stack[i].offset;
+
+                       /* Add the FDT_BEGIN_NODE tag of this supernode */
+                       fdt_next_tag(info->fdt, start, &stop_at);
+                       if (fdt_add_region(info, base + start, stop_at - start))
+                               return -1;
+
+                       /* Remember that this supernode is now included */
+                       info->stack[i].included = 1;
+                       info->can_merge = 1;
+               }
+
+               /* Force (later) generation of the FDT_END_NODE tag */
+               if (!info->stack[i].want)
+                       info->stack[i].want = WANT_NODES_ONLY;
+       }
+
+       return 0;
+}
+
+enum {
+       FDT_DONE_NOTHING,
+       FDT_DONE_MEM_RSVMAP,
+       FDT_DONE_STRUCT,
+       FDT_DONE_END,
+       FDT_DONE_STRINGS,
+       FDT_DONE_ALL,
+};
+
+int fdt_first_region(const void *fdt,
+               int (*h_include)(void *priv, const void *fdt, int offset,
+                                int type, const char *data, int size),
+               void *priv, struct fdt_region *region,
+               char *path, int path_len, int flags,
+               struct fdt_region_state *info)
+{
+       struct fdt_region_ptrs *p = &info->ptrs;
+
+       /* Set up our state */
+       info->fdt = fdt;
+       info->can_merge = 1;
+       info->max_regions = 1;
+       info->start = -1;
+       p->want = WANT_NOTHING;
+       p->end = path;
+       *p->end = '\0';
+       p->nextoffset = 0;
+       p->depth = -1;
+       p->done = FDT_DONE_NOTHING;
+
+       return fdt_next_region(fdt, h_include, priv, region,
+                              path, path_len, flags, info);
+}
+
+/***********************************************************************
+ *
+ *     Theory of operation
+ *
+ * Note: in this description 'included' means that a node (or other part
+ * of the tree) should be included in the region list, i.e. it will have
+ * a region which covers its part of the tree.
+ *
+ * This function maintains some state from the last time it is called.
+ * It checks the next part of the tree that it is supposed to look at
+ * (p.nextoffset) to see if that should be included or not. When it
+ * finds something to include, it sets info->start to its offset. This
+ * marks the start of the region we want to include.
+ *
+ * Once info->start is set to the start (i.e. not -1), we continue
+ * scanning until we find something that we don't want included. This
+ * will be the end of a region. At this point we can close off the
+ * region and add it to the list. So we do so, and reset info->start
+ * to -1.
+ *
+ * One complication here is that we want to merge regions. So when we
+ * come to add another region later, we may in fact merge it with the
+ * previous one if one ends where the other starts.
+ *
+ * The function fdt_add_region() will return -1 if it fails to add the
+ * region, because we already have a region ready to be returned, and
+ * the new one cannot be merged in with it. In this case, we must return
+ * the region we found, and wait for another call to this function.
+ * When it comes, we will repeat the processing of the tag and again
+ * try to add a region. This time it will succeed.
+ *
+ * The current state of the pointers (stack, offset, etc.) is maintained
+ * in a ptrs member. At the start of every loop iteration we make a copy
+ * of it.  The copy is then updated as the tag is processed. Only if we
+ * get to the end of the loop iteration (and successfully call
+ * fdt_add_region() if we need to) can we commit the changes we have
+ * made to these pointers. For example, if we see an FDT_END_NODE tag,
+ * we will decrement the depth value. But if we need to add a region
+ * for this tag (let's say because the previous tag is included and this
+ * FDT_END_NODE tag is not included) then we will only commit the result
+ * if we were able to add the region. That allows us to retry again next
+ * time.
+ *
+ * We keep track of a variable called 'want' which tells us what we want
+ * to include when there is no specific information provided by the
+ * h_include function for a particular property. This basically handles
+ * the inclusion of properties which are pulled in by virtue of the node
+ * they are in. So if you include a node, its properties are also
+ * included.  In this case 'want' will be WANT_NODES_AND_PROPS. The
+ * FDT_REG_DIRECT_SUBNODES feature also makes use of 'want'. While we
+ * are inside the subnode, 'want' will be set to WANT_NODES_ONLY, so
+ * that only the subnode's FDT_BEGIN_NODE and FDT_END_NODE tags will be
+ * included, and properties will be skipped. If WANT_NOTHING is
+ * selected, then we will just rely on what the h_include() function
+ * tells us.
+ *
+ * Using 'want' we work out 'include', which tells us whether this
+ * current tag should be included or not. As you can imagine, if the
+ * value of 'include' changes, that means we are on a boundary between
+ * nodes to include and nodes to exclude. At this point we either close
+ * off a previous region and add it to the list, or mark the start of a
+ * new region.
+ *
+ * Apart from the nodes, we have mem_rsvmap, the FDT_END tag and the
+ * string list. Each of these dealt with as a whole (i.e. we create a
+ * region for each if it is to be included). For mem_rsvmap we don't
+ * allow it to merge with the first struct region. For the stringlist,
+ * we don't allow it to merge with the last struct region (which
+ * contains at minimum the FDT_END tag).
+ *
+ *********************************************************************/
+
+int fdt_next_region(const void *fdt,
+               int (*h_include)(void *priv, const void *fdt, int offset,
+                                int type, const char *data, int size),
+               void *priv, struct fdt_region *region,
+               char *path, int path_len, int flags,
+               struct fdt_region_state *info)
+{
+       int base = fdt_off_dt_struct(fdt);
+       int last_node = 0;
+       const char *str;
+
+       info->region = region;
+       info->count = 0;
+       if (info->ptrs.done < FDT_DONE_MEM_RSVMAP &&
+           (flags & FDT_REG_ADD_MEM_RSVMAP)) {
+               /* Add the memory reserve map into its own region */
+               if (fdt_add_region(info, fdt_off_mem_rsvmap(fdt),
+                                  fdt_off_dt_struct(fdt) -
+                                  fdt_off_mem_rsvmap(fdt)))
+                       return 0;
+               info->can_merge = 0;    /* Don't allow merging with this */
+               info->ptrs.done = FDT_DONE_MEM_RSVMAP;
+       }
+
+       /*
+        * Work through the tags one by one, deciding whether each needs to
+        * be included or not. We set the variable 'include' to indicate our
+        * decision. 'want' is used to track what we want to include - it
+        * allows us to pick up all the properties (and/or subnode tags) of
+        * a node.
+        */
+       while (info->ptrs.done < FDT_DONE_STRUCT) {
+               const struct fdt_property *prop;
+               struct fdt_region_ptrs p;
+               const char *name;
+               int include = 0;
+               int stop_at = 0;
+               uint32_t tag;
+               int offset;
+               int val;
+               int len;
+
+               /*
+                * Make a copy of our pointers. If we make it to the end of
+                * this block then we will commit them back to info->ptrs.
+                * Otherwise we can try again from the same starting state
+                * next time we are called.
+                */
+               p = info->ptrs;
+
+               /*
+                * Find the tag, and the offset of the next one. If we need to
+                * stop including tags, then by default we stop *after*
+                * including the current tag
+                */
+               offset = p.nextoffset;
+               tag = fdt_next_tag(fdt, offset, &p.nextoffset);
+               stop_at = p.nextoffset;
+
+               switch (tag) {
+               case FDT_PROP:
+                       stop_at = offset;
+                       prop = fdt_get_property_by_offset(fdt, offset, NULL);
+                       str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+                       val = h_include(priv, fdt, last_node, FDT_IS_PROP, str,
+                                           strlen(str) + 1);
+                       if (val == -1) {
+                               include = p.want >= WANT_NODES_AND_PROPS;
+                       } else {
+                               include = val;
+                               /*
+                                * Make sure we include the } for this block.
+                                * It might be more correct to have this done
+                                * by the call to fdt_include_supernodes() in
+                                * the case where it adds the node we are
+                                * currently in, but this is equivalent.
+                                */
+                               if ((flags & FDT_REG_SUPERNODES) && val &&
+                                   !p.want)
+                                       p.want = WANT_NODES_ONLY;
+                       }
+
+                       /* Value grepping is not yet supported */
+                       break;
+
+               case FDT_NOP:
+                       include = p.want >= WANT_NODES_AND_PROPS;
+                       stop_at = offset;
+                       break;
+
+               case FDT_BEGIN_NODE:
+                       last_node = offset;
+                       p.depth++;
+                       if (p.depth == FDT_MAX_DEPTH)
+                               return -FDT_ERR_BADSTRUCTURE;
+                       name = fdt_get_name(fdt, offset, &len);
+                       if (p.end - path + 2 + len >= path_len)
+                               return -FDT_ERR_NOSPACE;
+
+                       /* Build the full path of this node */
+                       if (p.end != path + 1)
+                               *p.end++ = '/';
+                       strcpy(p.end, name);
+                       p.end += len;
+                       info->stack[p.depth].want = p.want;
+                       info->stack[p.depth].offset = offset;
+
+                       /*
+                        * If we are not intending to include this node unless
+                        * it matches, make sure we stop *before* its tag.
+                        */
+                       if (p.want == WANT_NODES_ONLY ||
+                           !(flags & (FDT_REG_DIRECT_SUBNODES |
+                                      FDT_REG_ALL_SUBNODES))) {
+                               stop_at = offset;
+                               p.want = WANT_NOTHING;
+                       }
+                       val = h_include(priv, fdt, offset, FDT_IS_NODE, path,
+                                       p.end - path + 1);
+
+                       /* Include this if requested */
+                       if (val) {
+                               p.want = (flags & FDT_REG_ALL_SUBNODES) ?
+                                       WANT_ALL_NODES_AND_PROPS :
+                                       WANT_NODES_AND_PROPS;
+                       }
+
+                       /* If not requested, decay our 'p.want' value */
+                       else if (p.want) {
+                               if (p.want != WANT_ALL_NODES_AND_PROPS)
+                                       p.want--;
+
+                       /* Not including this tag, so stop now */
+                       } else {
+                               stop_at = offset;
+                       }
+
+                       /*
+                        * Decide whether to include this tag, and update our
+                        * stack with the state for this node
+                        */
+                       include = p.want;
+                       info->stack[p.depth].included = include;
+                       break;
+
+               case FDT_END_NODE:
+                       include = p.want;
+                       if (p.depth < 0)
+                               return -FDT_ERR_BADSTRUCTURE;
+
+                       /*
+                        * If we don't want this node, stop right away, unless
+                        * we are including subnodes
+                        */
+                       if (!p.want && !(flags & FDT_REG_DIRECT_SUBNODES))
+                               stop_at = offset;
+                       p.want = info->stack[p.depth].want;
+                       p.depth--;
+                       while (p.end > path && *--p.end != '/')
+                               ;
+                       *p.end = '\0';
+                       break;
+
+               case FDT_END:
+                       /* We always include the end tag */
+                       include = 1;
+                       p.done = FDT_DONE_STRUCT;
+                       break;
+               }
+
+               /* If this tag is to be included, mark it as region start */
+               if (include && info->start == -1) {
+                       /* Include any supernodes required by this one */
+                       if (flags & FDT_REG_SUPERNODES) {
+                               if (fdt_include_supernodes(info, p.depth))
+                                       return 0;
+                       }
+                       info->start = offset;
+               }
+
+               /*
+                * If this tag is not to be included, finish up the current
+                * region.
+                */
+               if (!include && info->start != -1) {
+                       if (fdt_add_region(info, base + info->start,
+                                          stop_at - info->start))
+                               return 0;
+                       info->start = -1;
+                       info->can_merge = 1;
+               }
+
+               /* If we have made it this far, we can commit our pointers */
+               info->ptrs = p;
+       }
+
+       /* Add a region for the END tag and a separate one for string table */
+       if (info->ptrs.done < FDT_DONE_END) {
+               if (info->ptrs.nextoffset != fdt_size_dt_struct(fdt))
+                       return -FDT_ERR_BADSTRUCTURE;
+
+               if (fdt_add_region(info, base + info->start,
+                                  info->ptrs.nextoffset - info->start))
+                       return 0;
+               info->ptrs.done++;
+       }
+       if (info->ptrs.done < FDT_DONE_STRINGS) {
+               if (flags & FDT_REG_ADD_STRING_TAB) {
+                       info->can_merge = 0;
+                       if (fdt_off_dt_strings(fdt) <
+                           base + info->ptrs.nextoffset)
+                               return -FDT_ERR_BADLAYOUT;
+                       if (fdt_add_region(info, fdt_off_dt_strings(fdt),
+                                          fdt_size_dt_strings(fdt)))
+                               return 0;
+               }
+               info->ptrs.done++;
+       }
+
+       return info->count > 0 ? 0 : -FDT_ERR_NOTFOUND;
+}
diff --git a/boot/image-android-dt.c b/boot/image-android-dt.c
new file mode 100644 (file)
index 0000000..a2d52df
--- /dev/null
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 Linaro Ltd.
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ */
+
+#include <image-android-dt.h>
+#include <dt_table.h>
+#include <common.h>
+#include <linux/libfdt.h>
+#include <mapmem.h>
+
+/**
+ * Check if image header is correct.
+ *
+ * @param hdr_addr Start address of DT image
+ * @return true if header is correct or false if header is incorrect
+ */
+bool android_dt_check_header(ulong hdr_addr)
+{
+       const struct dt_table_header *hdr;
+       u32 magic;
+
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       magic = fdt32_to_cpu(hdr->magic);
+       unmap_sysmem(hdr);
+
+       return magic == DT_TABLE_MAGIC;
+}
+
+/**
+ * Get the address of FDT (dtb or dtbo) in memory by its index in image.
+ *
+ * @param hdr_addr Start address of DT image
+ * @param index Index of desired FDT in image (starting from 0)
+ * @param[out] addr If not NULL, will contain address to specified FDT
+ * @param[out] size If not NULL, will contain size of specified FDT
+ *
+ * @return true on success or false on error
+ */
+bool android_dt_get_fdt_by_index(ulong hdr_addr, u32 index, ulong *addr,
+                                u32 *size)
+{
+       const struct dt_table_header *hdr;
+       const struct dt_table_entry *e;
+       u32 entry_count, entries_offset, entry_size;
+       ulong e_addr;
+       u32 dt_offset, dt_size;
+
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       entry_count = fdt32_to_cpu(hdr->dt_entry_count);
+       entries_offset = fdt32_to_cpu(hdr->dt_entries_offset);
+       entry_size = fdt32_to_cpu(hdr->dt_entry_size);
+       unmap_sysmem(hdr);
+
+       if (index >= entry_count) {
+               printf("Error: index >= dt_entry_count (%u >= %u)\n", index,
+                      entry_count);
+               return false;
+       }
+
+       e_addr = hdr_addr + entries_offset + index * entry_size;
+       e = map_sysmem(e_addr, sizeof(*e));
+       dt_offset = fdt32_to_cpu(e->dt_offset);
+       dt_size = fdt32_to_cpu(e->dt_size);
+       unmap_sysmem(e);
+
+       if (addr)
+               *addr = hdr_addr + dt_offset;
+       if (size)
+               *size = dt_size;
+
+       return true;
+}
+
+#if !defined(CONFIG_SPL_BUILD)
+static void android_dt_print_fdt_info(const struct fdt_header *fdt)
+{
+       u32 fdt_size;
+       int root_node_off;
+       const char *compatible;
+
+       root_node_off = fdt_path_offset(fdt, "/");
+       if (root_node_off < 0) {
+               printf("Error: Root node not found\n");
+               return;
+       }
+
+       fdt_size = fdt_totalsize(fdt);
+       compatible = fdt_getprop(fdt, root_node_off, "compatible",
+                                NULL);
+
+       printf("           (FDT)size = %d\n", fdt_size);
+       printf("     (FDT)compatible = %s\n",
+              compatible ? compatible : "(unknown)");
+}
+
+/**
+ * Print information about DT image structure.
+ *
+ * @param hdr_addr Start address of DT image
+ */
+void android_dt_print_contents(ulong hdr_addr)
+{
+       const struct dt_table_header *hdr;
+       u32 entry_count, entries_offset, entry_size;
+       u32 i;
+
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       entry_count = fdt32_to_cpu(hdr->dt_entry_count);
+       entries_offset = fdt32_to_cpu(hdr->dt_entries_offset);
+       entry_size = fdt32_to_cpu(hdr->dt_entry_size);
+
+       /* Print image header info */
+       printf("dt_table_header:\n");
+       printf("               magic = %08x\n", fdt32_to_cpu(hdr->magic));
+       printf("          total_size = %d\n", fdt32_to_cpu(hdr->total_size));
+       printf("         header_size = %d\n", fdt32_to_cpu(hdr->header_size));
+       printf("       dt_entry_size = %d\n", entry_size);
+       printf("      dt_entry_count = %d\n", entry_count);
+       printf("   dt_entries_offset = %d\n", entries_offset);
+       printf("           page_size = %d\n", fdt32_to_cpu(hdr->page_size));
+       printf("             version = %d\n", fdt32_to_cpu(hdr->version));
+
+       unmap_sysmem(hdr);
+
+       /* Print image entries info */
+       for (i = 0; i < entry_count; ++i) {
+               const ulong e_addr = hdr_addr + entries_offset + i * entry_size;
+               const struct dt_table_entry *e;
+               const struct fdt_header *fdt;
+               u32 dt_offset, dt_size;
+               u32 j;
+
+               e = map_sysmem(e_addr, sizeof(*e));
+               dt_offset = fdt32_to_cpu(e->dt_offset);
+               dt_size = fdt32_to_cpu(e->dt_size);
+
+               printf("dt_table_entry[%d]:\n", i);
+               printf("             dt_size = %d\n", dt_size);
+               printf("           dt_offset = %d\n", dt_offset);
+               printf("                  id = %08x\n", fdt32_to_cpu(e->id));
+               printf("                 rev = %08x\n", fdt32_to_cpu(e->rev));
+               for (j = 0; j < 4; ++j) {
+                       printf("           custom[%d] = %08x\n", j,
+                              fdt32_to_cpu(e->custom[j]));
+               }
+
+               unmap_sysmem(e);
+
+               /* Print FDT info for this entry */
+               fdt = map_sysmem(hdr_addr + dt_offset, sizeof(*fdt));
+               android_dt_print_fdt_info(fdt);
+               unmap_sysmem(fdt);
+       }
+}
+#endif
diff --git a/boot/image-android.c b/boot/image-android.c
new file mode 100644 (file)
index 0000000..1fbbbba
--- /dev/null
@@ -0,0 +1,539 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ */
+
+#include <common.h>
+#include <env.h>
+#include <image.h>
+#include <image-android-dt.h>
+#include <android_image.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm/unaligned.h>
+#include <mapmem.h>
+#include <linux/libfdt.h>
+
+#define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR      0x10008000
+
+static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
+
+static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
+{
+       /*
+        * All the Android tools that generate a boot.img use this
+        * address as the default.
+        *
+        * Even though it doesn't really make a lot of sense, and it
+        * might be valid on some platforms, we treat that adress as
+        * the default value for this field, and try to execute the
+        * kernel in place in such a case.
+        *
+        * Otherwise, we will return the actual value set by the user.
+        */
+       if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR)
+               return (ulong)hdr + hdr->page_size;
+
+       /*
+        * abootimg creates images where all load addresses are 0
+        * and we need to fix them.
+        */
+       if (hdr->kernel_addr == 0 && hdr->ramdisk_addr == 0)
+               return env_get_ulong("kernel_addr_r", 16, 0);
+
+       return hdr->kernel_addr;
+}
+
+/**
+ * android_image_get_kernel() - processes kernel part of Android boot images
+ * @hdr:       Pointer to image header, which is at the start
+ *                     of the image.
+ * @verify:    Checksum verification flag. Currently unimplemented.
+ * @os_data:   Pointer to a ulong variable, will hold os data start
+ *                     address.
+ * @os_len:    Pointer to a ulong variable, will hold os data length.
+ *
+ * This function returns the os image's start address and length. Also,
+ * it appends the kernel command line to the bootargs env variable.
+ *
+ * Return: Zero, os start address and length on success,
+ *             otherwise on failure.
+ */
+int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
+                            ulong *os_data, ulong *os_len)
+{
+       u32 kernel_addr = android_image_get_kernel_addr(hdr);
+       const struct image_header *ihdr = (const struct image_header *)
+               ((uintptr_t)hdr + hdr->page_size);
+
+       /*
+        * Not all Android tools use the id field for signing the image with
+        * sha1 (or anything) so we don't check it. It is not obvious that the
+        * string is null terminated so we take care of this.
+        */
+       strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE);
+       andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0';
+       if (strlen(andr_tmp_str))
+               printf("Android's image name: %s\n", andr_tmp_str);
+
+       printf("Kernel load addr 0x%08x size %u KiB\n",
+              kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
+
+       int len = 0;
+       if (*hdr->cmdline) {
+               printf("Kernel command line: %s\n", hdr->cmdline);
+               len += strlen(hdr->cmdline);
+       }
+
+       char *bootargs = env_get("bootargs");
+       if (bootargs)
+               len += strlen(bootargs);
+
+       char *newbootargs = malloc(len + 2);
+       if (!newbootargs) {
+               puts("Error: malloc in android_image_get_kernel failed!\n");
+               return -ENOMEM;
+       }
+       *newbootargs = '\0';
+
+       if (bootargs) {
+               strcpy(newbootargs, bootargs);
+               strcat(newbootargs, " ");
+       }
+       if (*hdr->cmdline)
+               strcat(newbootargs, hdr->cmdline);
+
+       env_set("bootargs", newbootargs);
+
+       if (os_data) {
+               if (image_get_magic(ihdr) == IH_MAGIC) {
+                       *os_data = image_get_data(ihdr);
+               } else {
+                       *os_data = (ulong)hdr;
+                       *os_data += hdr->page_size;
+               }
+       }
+       if (os_len) {
+               if (image_get_magic(ihdr) == IH_MAGIC)
+                       *os_len = image_get_data_size(ihdr);
+               else
+                       *os_len = hdr->kernel_size;
+       }
+       return 0;
+}
+
+int android_image_check_header(const struct andr_img_hdr *hdr)
+{
+       return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE);
+}
+
+ulong android_image_get_end(const struct andr_img_hdr *hdr)
+{
+       ulong end;
+
+       /*
+        * The header takes a full page, the remaining components are aligned
+        * on page boundary
+        */
+       end = (ulong)hdr;
+       end += hdr->page_size;
+       end += ALIGN(hdr->kernel_size, hdr->page_size);
+       end += ALIGN(hdr->ramdisk_size, hdr->page_size);
+       end += ALIGN(hdr->second_size, hdr->page_size);
+
+       if (hdr->header_version >= 1)
+               end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
+
+       if (hdr->header_version >= 2)
+               end += ALIGN(hdr->dtb_size, hdr->page_size);
+
+       return end;
+}
+
+ulong android_image_get_kload(const struct andr_img_hdr *hdr)
+{
+       return android_image_get_kernel_addr(hdr);
+}
+
+ulong android_image_get_kcomp(const struct andr_img_hdr *hdr)
+{
+       const void *p = (void *)((uintptr_t)hdr + hdr->page_size);
+
+       if (image_get_magic((image_header_t *)p) == IH_MAGIC)
+               return image_get_comp((image_header_t *)p);
+       else if (get_unaligned_le32(p) == LZ4F_MAGIC)
+               return IH_COMP_LZ4;
+       else
+               return image_decomp_type(p, sizeof(u32));
+}
+
+int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
+                             ulong *rd_data, ulong *rd_len)
+{
+       if (!hdr->ramdisk_size) {
+               *rd_data = *rd_len = 0;
+               return -1;
+       }
+
+       printf("RAM disk load addr 0x%08x size %u KiB\n",
+              hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
+
+       *rd_data = (unsigned long)hdr;
+       *rd_data += hdr->page_size;
+       *rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
+
+       *rd_len = hdr->ramdisk_size;
+       return 0;
+}
+
+int android_image_get_second(const struct andr_img_hdr *hdr,
+                             ulong *second_data, ulong *second_len)
+{
+       if (!hdr->second_size) {
+               *second_data = *second_len = 0;
+               return -1;
+       }
+
+       *second_data = (unsigned long)hdr;
+       *second_data += hdr->page_size;
+       *second_data += ALIGN(hdr->kernel_size, hdr->page_size);
+       *second_data += ALIGN(hdr->ramdisk_size, hdr->page_size);
+
+       printf("second address is 0x%lx\n",*second_data);
+
+       *second_len = hdr->second_size;
+       return 0;
+}
+
+/**
+ * android_image_get_dtbo() - Get address and size of recovery DTBO image.
+ * @hdr_addr: Boot image header address
+ * @addr: If not NULL, will contain address of recovery DTBO image
+ * @size: If not NULL, will contain size of recovery DTBO image
+ *
+ * Get the address and size of DTBO image in "Recovery DTBO" area of Android
+ * Boot Image in RAM. The format of this image is Android DTBO (see
+ * corresponding "DTB/DTBO Partitions" AOSP documentation for details). Once
+ * the address is obtained from this function, one can use 'adtimg' U-Boot
+ * command or android_dt_*() functions to extract desired DTBO blob.
+ *
+ * This DTBO (included in boot image) is only needed for non-A/B devices, and it
+ * only can be found in recovery image. On A/B devices we can always rely on
+ * "dtbo" partition. See "Including DTBO in Recovery for Non-A/B Devices" in
+ * AOSP documentation for details.
+ *
+ * Return: true on success or false on error.
+ */
+bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size)
+{
+       const struct andr_img_hdr *hdr;
+       ulong dtbo_img_addr;
+       bool ret = true;
+
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       if (android_image_check_header(hdr)) {
+               printf("Error: Boot Image header is incorrect\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->header_version < 1) {
+               printf("Error: header_version must be >= 1 to get dtbo\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->recovery_dtbo_size == 0) {
+               printf("Error: recovery_dtbo_size is 0\n");
+               ret = false;
+               goto exit;
+       }
+
+       /* Calculate the address of DTB area in boot image */
+       dtbo_img_addr = hdr_addr;
+       dtbo_img_addr += hdr->page_size;
+       dtbo_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
+       dtbo_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
+       dtbo_img_addr += ALIGN(hdr->second_size, hdr->page_size);
+
+       if (addr)
+               *addr = dtbo_img_addr;
+       if (size)
+               *size = hdr->recovery_dtbo_size;
+
+exit:
+       unmap_sysmem(hdr);
+       return ret;
+}
+
+/**
+ * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image.
+ * @hdr_addr: Boot image header address
+ * @addr: Will contain the address of DTB area in boot image
+ *
+ * Return: true on success or false on fail.
+ */
+static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong *addr)
+{
+       const struct andr_img_hdr *hdr;
+       ulong dtb_img_addr;
+       bool ret = true;
+
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       if (android_image_check_header(hdr)) {
+               printf("Error: Boot Image header is incorrect\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->header_version < 2) {
+               printf("Error: header_version must be >= 2 to get dtb\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->dtb_size == 0) {
+               printf("Error: dtb_size is 0\n");
+               ret = false;
+               goto exit;
+       }
+
+       /* Calculate the address of DTB area in boot image */
+       dtb_img_addr = hdr_addr;
+       dtb_img_addr += hdr->page_size;
+       dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
+       dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
+       dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size);
+       dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
+
+       *addr = dtb_img_addr;
+
+exit:
+       unmap_sysmem(hdr);
+       return ret;
+}
+
+/**
+ * android_image_get_dtb_by_index() - Get address and size of blob in DTB area.
+ * @hdr_addr: Boot image header address
+ * @index: Index of desired DTB in DTB area (starting from 0)
+ * @addr: If not NULL, will contain address to specified DTB
+ * @size: If not NULL, will contain size of specified DTB
+ *
+ * Get the address and size of DTB blob by its index in DTB area of Android
+ * Boot Image in RAM.
+ *
+ * Return: true on success or false on error.
+ */
+bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr,
+                                   u32 *size)
+{
+       const struct andr_img_hdr *hdr;
+       bool res;
+       ulong dtb_img_addr;     /* address of DTB part in boot image */
+       u32 dtb_img_size;       /* size of DTB payload in boot image */
+       ulong dtb_addr;         /* address of DTB blob with specified index  */
+       u32 i;                  /* index iterator */
+
+       res = android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr);
+       if (!res)
+               return false;
+
+       /* Check if DTB area of boot image is in DTBO format */
+       if (android_dt_check_header(dtb_img_addr)) {
+               return android_dt_get_fdt_by_index(dtb_img_addr, index, addr,
+                                                  size);
+       }
+
+       /* Find out the address of DTB with specified index in concat blobs */
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       dtb_img_size = hdr->dtb_size;
+       unmap_sysmem(hdr);
+       i = 0;
+       dtb_addr = dtb_img_addr;
+       while (dtb_addr < dtb_img_addr + dtb_img_size) {
+               const struct fdt_header *fdt;
+               u32 dtb_size;
+
+               fdt = map_sysmem(dtb_addr, sizeof(*fdt));
+               if (fdt_check_header(fdt) != 0) {
+                       unmap_sysmem(fdt);
+                       printf("Error: Invalid FDT header for index %u\n", i);
+                       return false;
+               }
+
+               dtb_size = fdt_totalsize(fdt);
+               unmap_sysmem(fdt);
+
+               if (i == index) {
+                       if (size)
+                               *size = dtb_size;
+                       if (addr)
+                               *addr = dtb_addr;
+                       return true;
+               }
+
+               dtb_addr += dtb_size;
+               ++i;
+       }
+
+       printf("Error: Index is out of bounds (%u/%u)\n", index, i);
+       return false;
+}
+
+#if !defined(CONFIG_SPL_BUILD)
+/**
+ * android_print_contents - prints out the contents of the Android format image
+ * @hdr: pointer to the Android format image header
+ *
+ * android_print_contents() formats a multi line Android image contents
+ * description.
+ * The routine prints out Android image properties
+ *
+ * returns:
+ *     no returned results
+ */
+void android_print_contents(const struct andr_img_hdr *hdr)
+{
+       const char * const p = IMAGE_INDENT_STRING;
+       /* os_version = ver << 11 | lvl */
+       u32 os_ver = hdr->os_version >> 11;
+       u32 os_lvl = hdr->os_version & ((1U << 11) - 1);
+
+       printf("%skernel size:          %x\n", p, hdr->kernel_size);
+       printf("%skernel address:       %x\n", p, hdr->kernel_addr);
+       printf("%sramdisk size:         %x\n", p, hdr->ramdisk_size);
+       printf("%sramdisk address:      %x\n", p, hdr->ramdisk_addr);
+       printf("%ssecond size:          %x\n", p, hdr->second_size);
+       printf("%ssecond address:       %x\n", p, hdr->second_addr);
+       printf("%stags address:         %x\n", p, hdr->tags_addr);
+       printf("%spage size:            %x\n", p, hdr->page_size);
+       /* ver = A << 14 | B << 7 | C         (7 bits for each of A, B, C)
+        * lvl = ((Y - 2000) & 127) << 4 | M  (7 bits for Y, 4 bits for M) */
+       printf("%sos_version:           %x (ver: %u.%u.%u, level: %u.%u)\n",
+              p, hdr->os_version,
+              (os_ver >> 7) & 0x7F, (os_ver >> 14) & 0x7F, os_ver & 0x7F,
+              (os_lvl >> 4) + 2000, os_lvl & 0x0F);
+       printf("%sname:                 %s\n", p, hdr->name);
+       printf("%scmdline:              %s\n", p, hdr->cmdline);
+       printf("%sheader_version:       %d\n", p, hdr->header_version);
+
+       if (hdr->header_version >= 1) {
+               printf("%srecovery dtbo size:   %x\n", p,
+                      hdr->recovery_dtbo_size);
+               printf("%srecovery dtbo offset: %llx\n", p,
+                      hdr->recovery_dtbo_offset);
+               printf("%sheader size:          %x\n", p,
+                      hdr->header_size);
+       }
+
+       if (hdr->header_version >= 2) {
+               printf("%sdtb size:             %x\n", p, hdr->dtb_size);
+               printf("%sdtb addr:             %llx\n", p, hdr->dtb_addr);
+       }
+}
+
+/**
+ * android_image_print_dtb_info - Print info for one DTB blob in DTB area.
+ * @fdt: DTB header
+ * @index: Number of DTB blob in DTB area.
+ *
+ * Return: true on success or false on error.
+ */
+static bool android_image_print_dtb_info(const struct fdt_header *fdt,
+                                        u32 index)
+{
+       int root_node_off;
+       u32 fdt_size;
+       const char *model;
+       const char *compatible;
+
+       root_node_off = fdt_path_offset(fdt, "/");
+       if (root_node_off < 0) {
+               printf("Error: Root node not found\n");
+               return false;
+       }
+
+       fdt_size = fdt_totalsize(fdt);
+       compatible = fdt_getprop(fdt, root_node_off, "compatible",
+                                NULL);
+       model = fdt_getprop(fdt, root_node_off, "model", NULL);
+
+       printf(" - DTB #%u:\n", index);
+       printf("           (DTB)size = %d\n", fdt_size);
+       printf("          (DTB)model = %s\n", model ? model : "(unknown)");
+       printf("     (DTB)compatible = %s\n",
+              compatible ? compatible : "(unknown)");
+
+       return true;
+}
+
+/**
+ * android_image_print_dtb_contents() - Print info for DTB blobs in DTB area.
+ * @hdr_addr: Boot image header address
+ *
+ * DTB payload in Android Boot Image v2+ can be in one of following formats:
+ *   1. Concatenated DTB blobs
+ *   2. Android DTBO format (see CONFIG_CMD_ADTIMG for details)
+ *
+ * This function does next:
+ *   1. Prints out the format used in DTB area
+ *   2. Iterates over all DTB blobs in DTB area and prints out the info for
+ *      each blob.
+ *
+ * Return: true on success or false on error.
+ */
+bool android_image_print_dtb_contents(ulong hdr_addr)
+{
+       const struct andr_img_hdr *hdr;
+       bool res;
+       ulong dtb_img_addr;     /* address of DTB part in boot image */
+       u32 dtb_img_size;       /* size of DTB payload in boot image */
+       ulong dtb_addr;         /* address of DTB blob with specified index  */
+       u32 i;                  /* index iterator */
+
+       res = android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr);
+       if (!res)
+               return false;
+
+       /* Check if DTB area of boot image is in DTBO format */
+       if (android_dt_check_header(dtb_img_addr)) {
+               printf("## DTB area contents (DTBO format):\n");
+               android_dt_print_contents(dtb_img_addr);
+               return true;
+       }
+
+       printf("## DTB area contents (concat format):\n");
+
+       /* Iterate over concatenated DTB blobs */
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       dtb_img_size = hdr->dtb_size;
+       unmap_sysmem(hdr);
+       i = 0;
+       dtb_addr = dtb_img_addr;
+       while (dtb_addr < dtb_img_addr + dtb_img_size) {
+               const struct fdt_header *fdt;
+               u32 dtb_size;
+
+               fdt = map_sysmem(dtb_addr, sizeof(*fdt));
+               if (fdt_check_header(fdt) != 0) {
+                       unmap_sysmem(fdt);
+                       printf("Error: Invalid FDT header for index %u\n", i);
+                       return false;
+               }
+
+               res = android_image_print_dtb_info(fdt, i);
+               if (!res) {
+                       unmap_sysmem(fdt);
+                       return false;
+               }
+
+               dtb_size = fdt_totalsize(fdt);
+               unmap_sysmem(fdt);
+               dtb_addr += dtb_size;
+               ++i;
+       }
+
+       return true;
+}
+#endif
diff --git a/boot/image-board.c b/boot/image-board.c
new file mode 100644 (file)
index 0000000..ddf30c6
--- /dev/null
@@ -0,0 +1,956 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Image code used by boards (and not host tools)
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <bootstage.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <fpga.h>
+#include <image.h>
+#include <mapmem.h>
+#include <rtc.h>
+#include <watchdog.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+
+#ifndef CONFIG_SYS_BARGSIZE
+#define CONFIG_SYS_BARGSIZE 512
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * image_get_ramdisk - get and verify ramdisk image
+ * @rd_addr: ramdisk image start address
+ * @arch: expected ramdisk architecture
+ * @verify: checksum verification flag
+ *
+ * image_get_ramdisk() returns a pointer to the verified ramdisk image
+ * header. Routine receives image start address and expected architecture
+ * flag. Verification done covers data and header integrity and os/type/arch
+ * fields checking.
+ *
+ * returns:
+ *     pointer to a ramdisk image header, if image was found and valid
+ *     otherwise, return NULL
+ */
+static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch,
+                                              int verify)
+{
+       const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
+
+       if (!image_check_magic(rd_hdr)) {
+               puts("Bad Magic Number\n");
+               bootstage_error(BOOTSTAGE_ID_RD_MAGIC);
+               return NULL;
+       }
+
+       if (!image_check_hcrc(rd_hdr)) {
+               puts("Bad Header Checksum\n");
+               bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
+               return NULL;
+       }
+
+       bootstage_mark(BOOTSTAGE_ID_RD_MAGIC);
+       image_print_contents(rd_hdr);
+
+       if (verify) {
+               puts("   Verifying Checksum ... ");
+               if (!image_check_dcrc(rd_hdr)) {
+                       puts("Bad Data CRC\n");
+                       bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM);
+                       return NULL;
+               }
+               puts("OK\n");
+       }
+
+       bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
+
+       if (!image_check_os(rd_hdr, IH_OS_LINUX) ||
+           !image_check_arch(rd_hdr, arch) ||
+           !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) {
+               printf("No Linux %s Ramdisk Image\n",
+                      genimg_get_arch_name(arch));
+               bootstage_error(BOOTSTAGE_ID_RAMDISK);
+               return NULL;
+       }
+
+       return rd_hdr;
+}
+
+/*****************************************************************************/
+/* Shared dual-format routines */
+/*****************************************************************************/
+ulong image_load_addr = CONFIG_SYS_LOAD_ADDR;  /* Default Load Address */
+ulong image_save_addr;                 /* Default Save Address */
+ulong image_save_size;                 /* Default Save Size (in bytes) */
+
+static int on_loadaddr(const char *name, const char *value, enum env_op op,
+                      int flags)
+{
+       switch (op) {
+       case env_op_create:
+       case env_op_overwrite:
+               image_load_addr = hextoul(value, NULL);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr);
+
+ulong env_get_bootm_low(void)
+{
+       char *s = env_get("bootm_low");
+
+       if (s) {
+               ulong tmp = hextoul(s, NULL);
+               return tmp;
+       }
+
+#if defined(CONFIG_SYS_SDRAM_BASE)
+       return CONFIG_SYS_SDRAM_BASE;
+#elif defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_RISCV)
+       return gd->bd->bi_dram[0].start;
+#else
+       return 0;
+#endif
+}
+
+phys_size_t env_get_bootm_size(void)
+{
+       phys_size_t tmp, size;
+       phys_addr_t start;
+       char *s = env_get("bootm_size");
+
+       if (s) {
+               tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
+               return tmp;
+       }
+
+       start = gd->ram_base;
+       size = gd->ram_size;
+
+       if (start + size > gd->ram_top)
+               size = gd->ram_top - start;
+
+       s = env_get("bootm_low");
+       if (s)
+               tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
+       else
+               tmp = start;
+
+       return size - (tmp - start);
+}
+
+phys_size_t env_get_bootm_mapsize(void)
+{
+       phys_size_t tmp;
+       char *s = env_get("bootm_mapsize");
+
+       if (s) {
+               tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
+               return tmp;
+       }
+
+#if defined(CONFIG_SYS_BOOTMAPSZ)
+       return CONFIG_SYS_BOOTMAPSZ;
+#else
+       return env_get_bootm_size();
+#endif
+}
+
+void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
+{
+       if (to == from)
+               return;
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+       if (to > from) {
+               from += len;
+               to += len;
+       }
+       while (len > 0) {
+               size_t tail = (len > chunksz) ? chunksz : len;
+
+               WATCHDOG_RESET();
+               if (to > from) {
+                       to -= tail;
+                       from -= tail;
+               }
+               memmove(to, from, tail);
+               if (to < from) {
+                       to += tail;
+                       from += tail;
+               }
+               len -= tail;
+       }
+#else  /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
+       memmove(to, from, len);
+#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+}
+
+/**
+ * genimg_get_kernel_addr_fit - get the real kernel address and return 2
+ *                              FIT strings
+ * @img_addr: a string might contain real image address
+ * @fit_uname_config: double pointer to a char, will hold pointer to a
+ *                    configuration unit name
+ * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage
+ *                    name
+ *
+ * genimg_get_kernel_addr_fit get the real kernel start address from a string
+ * which is normally the first argv of bootm/bootz
+ *
+ * returns:
+ *     kernel start address
+ */
+ulong genimg_get_kernel_addr_fit(char * const img_addr,
+                                const char **fit_uname_config,
+                                const char **fit_uname_kernel)
+{
+       ulong kernel_addr;
+
+       /* find out kernel image address */
+       if (!img_addr) {
+               kernel_addr = image_load_addr;
+               debug("*  kernel: default image load address = 0x%08lx\n",
+                     image_load_addr);
+       } else if (CONFIG_IS_ENABLED(FIT) &&
+                  fit_parse_conf(img_addr, image_load_addr, &kernel_addr,
+                                 fit_uname_config)) {
+               debug("*  kernel: config '%s' from image at 0x%08lx\n",
+                     *fit_uname_config, kernel_addr);
+       } else if (CONFIG_IS_ENABLED(FIT) &&
+                  fit_parse_subimage(img_addr, image_load_addr, &kernel_addr,
+                                     fit_uname_kernel)) {
+               debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
+                     *fit_uname_kernel, kernel_addr);
+       } else {
+               kernel_addr = hextoul(img_addr, NULL);
+               debug("*  kernel: cmdline image address = 0x%08lx\n",
+                     kernel_addr);
+       }
+
+       return kernel_addr;
+}
+
+/**
+ * genimg_get_kernel_addr() is the simple version of
+ * genimg_get_kernel_addr_fit(). It ignores those return FIT strings
+ */
+ulong genimg_get_kernel_addr(char * const img_addr)
+{
+       const char *fit_uname_config = NULL;
+       const char *fit_uname_kernel = NULL;
+
+       return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config,
+                                         &fit_uname_kernel);
+}
+
+/**
+ * genimg_get_format - get image format type
+ * @img_addr: image start address
+ *
+ * genimg_get_format() checks whether provided address points to a valid
+ * legacy or FIT image.
+ *
+ * New uImage format and FDT blob are based on a libfdt. FDT blob
+ * may be passed directly or embedded in a FIT image. In both situations
+ * genimg_get_format() must be able to dectect libfdt header.
+ *
+ * returns:
+ *     image format type or IMAGE_FORMAT_INVALID if no image is present
+ */
+int genimg_get_format(const void *img_addr)
+{
+       if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
+               const image_header_t *hdr;
+
+               hdr = (const image_header_t *)img_addr;
+               if (image_check_magic(hdr))
+                       return IMAGE_FORMAT_LEGACY;
+       }
+       if (CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT)) {
+               if (!fdt_check_header(img_addr))
+                       return IMAGE_FORMAT_FIT;
+       }
+       if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE) &&
+           !android_image_check_header(img_addr))
+               return IMAGE_FORMAT_ANDROID;
+
+       return IMAGE_FORMAT_INVALID;
+}
+
+/**
+ * fit_has_config - check if there is a valid FIT configuration
+ * @images: pointer to the bootm command headers structure
+ *
+ * fit_has_config() checks if there is a FIT configuration in use
+ * (if FTI support is present).
+ *
+ * returns:
+ *     0, no FIT support or no configuration found
+ *     1, configuration found
+ */
+int genimg_has_config(bootm_headers_t *images)
+{
+       if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg)
+               return 1;
+
+       return 0;
+}
+
+/**
+ * select_ramdisk() - Select and locate the ramdisk to use
+ *
+ * @images: pointer to the bootm images structure
+ * @select: name of ramdisk to select, or NULL for any
+ * @arch: expected ramdisk architecture
+ * @rd_datap: pointer to a ulong variable, will hold ramdisk pointer
+ * @rd_lenp: pointer to a ulong variable, will hold ramdisk length
+ * @return 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported),
+ *     other -ve value on other error
+ */
+static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
+                         ulong *rd_datap, ulong *rd_lenp)
+{
+       ulong rd_addr = 0;
+       char *buf;
+       const char *fit_uname_config = images->fit_uname_cfg;
+       const char *fit_uname_ramdisk = NULL;
+       bool processed;
+       int rd_noffset;
+
+       if (select) {
+               ulong default_addr;
+               bool done = true;
+
+               if (CONFIG_IS_ENABLED(FIT)) {
+                       /*
+                        * If the init ramdisk comes from the FIT image and
+                        * the FIT image address is omitted in the command
+                        * line argument, try to use os FIT image address or
+                        * default load address.
+                        */
+                       if (images->fit_uname_os)
+                               default_addr = (ulong)images->fit_hdr_os;
+                       else
+                               default_addr = image_load_addr;
+
+                       if (fit_parse_conf(select, default_addr, &rd_addr,
+                                          &fit_uname_config)) {
+                               debug("*  ramdisk: config '%s' from image at 0x%08lx\n",
+                                     fit_uname_config, rd_addr);
+                       } else if (fit_parse_subimage(select, default_addr,
+                                                     &rd_addr,
+                                                     &fit_uname_ramdisk)) {
+                               debug("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
+                                     fit_uname_ramdisk, rd_addr);
+                       } else {
+                               done = false;
+                       }
+               }
+               if (!done) {
+                       rd_addr = hextoul(select, NULL);
+                       debug("*  ramdisk: cmdline image address = 0x%08lx\n",
+                             rd_addr);
+               }
+       } else if (CONFIG_IS_ENABLED(FIT)) {
+               /* use FIT configuration provided in first bootm
+                * command argument. If the property is not defined,
+                * quit silently (with -ENOPKG  )
+                */
+               rd_addr = map_to_sysmem(images->fit_hdr_os);
+               rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP,
+                                                     rd_addr);
+               if (rd_noffset == -ENOENT)
+                       return -ENOPKG;
+               else if (rd_noffset < 0)
+                       return rd_noffset;
+       }
+
+       /*
+        * Check if there is an initrd image at the
+        * address provided in the second bootm argument
+        * check image type, for FIT images get FIT node.
+        */
+       buf = map_sysmem(rd_addr, 0);
+       processed = false;
+       switch (genimg_get_format(buf)) {
+       case IMAGE_FORMAT_LEGACY:
+               if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
+                       const image_header_t *rd_hdr;
+
+                       printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n",
+                              rd_addr);
+
+                       bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
+                       rd_hdr = image_get_ramdisk(rd_addr, arch, images->verify);
+                       if (!rd_hdr)
+                               return -ENOENT;
+
+                       *rd_datap = image_get_data(rd_hdr);
+                       *rd_lenp = image_get_data_size(rd_hdr);
+                       processed = true;
+               }
+               break;
+       case IMAGE_FORMAT_FIT:
+               if (CONFIG_IS_ENABLED(FIT)) {
+                       rd_noffset = fit_image_load(images, rd_addr,
+                                                   &fit_uname_ramdisk,
+                                                   &fit_uname_config, arch,
+                                                   IH_TYPE_RAMDISK,
+                                                   BOOTSTAGE_ID_FIT_RD_START,
+                                                   FIT_LOAD_OPTIONAL_NON_ZERO,
+                                                   rd_datap, rd_lenp);
+                       if (rd_noffset < 0)
+                               return rd_noffset;
+
+                       images->fit_hdr_rd = map_sysmem(rd_addr, 0);
+                       images->fit_uname_rd = fit_uname_ramdisk;
+                       images->fit_noffset_rd = rd_noffset;
+                       processed = true;
+               }
+               break;
+       case IMAGE_FORMAT_ANDROID:
+               if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
+                       android_image_get_ramdisk((void *)images->os.start,
+                                                 rd_datap, rd_lenp);
+                       processed = true;
+               }
+               break;
+       }
+
+       if (!processed) {
+               if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
+                       char *end = NULL;
+
+                       if (select)
+                               end = strchr(select, ':');
+                       if (end) {
+                               *rd_lenp = hextoul(++end, NULL);
+                               *rd_datap = rd_addr;
+                               processed = true;
+                       }
+               }
+
+               if (!processed) {
+                       puts("Wrong Ramdisk Image Format\n");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * boot_get_ramdisk - main ramdisk handling routine
+ * @argc: command argument count
+ * @argv: command argument list
+ * @images: pointer to the bootm images structure
+ * @arch: expected ramdisk architecture
+ * @rd_start: pointer to a ulong variable, will hold ramdisk start address
+ * @rd_end: pointer to a ulong variable, will hold ramdisk end
+ *
+ * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
+ * Currently supported are the following ramdisk sources:
+ *      - multicomponent kernel/ramdisk image,
+ *      - commandline provided address of decicated ramdisk image.
+ *
+ * returns:
+ *     0, if ramdisk image was found and valid, or skiped
+ *     rd_start and rd_end are set to ramdisk start/end addresses if
+ *     ramdisk image is found and valid
+ *
+ *     1, if ramdisk image is found but corrupted, or invalid
+ *     rd_start and rd_end are set to 0 if no ramdisk exists
+ */
+int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images,
+                    u8 arch, ulong *rd_start, ulong *rd_end)
+{
+       ulong rd_data, rd_len;
+       const char *select = NULL;
+
+       *rd_start = 0;
+       *rd_end = 0;
+
+       if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
+               char *buf;
+
+               /* Look for an Android boot image */
+               buf = map_sysmem(images->os.start, 0);
+               if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID)
+                       select = (argc == 0) ? env_get("loadaddr") : argv[0];
+       }
+
+       if (argc >= 2)
+               select = argv[1];
+
+       /*
+        * Look for a '-' which indicates to ignore the
+        * ramdisk argument
+        */
+       if (select && strcmp(select, "-") ==  0) {
+               debug("## Skipping init Ramdisk\n");
+               rd_len = 0;
+               rd_data = 0;
+       } else if (select || genimg_has_config(images)) {
+               int ret;
+
+               ret = select_ramdisk(images, select, arch, &rd_data, &rd_len);
+               if (ret == -ENOPKG)
+                       return 0;
+               else if (ret)
+                       return ret;
+       } else if (images->legacy_hdr_valid &&
+                       image_check_type(&images->legacy_hdr_os_copy,
+                                        IH_TYPE_MULTI)) {
+               /*
+                * Now check if we have a legacy mult-component image,
+                * get second entry data start address and len.
+                */
+               bootstage_mark(BOOTSTAGE_ID_RAMDISK);
+               printf("## Loading init Ramdisk from multi component Legacy Image at %08lx ...\n",
+                      (ulong)images->legacy_hdr_os);
+
+               image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
+       } else {
+               /*
+                * no initrd image
+                */
+               bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK);
+               rd_len = 0;
+               rd_data = 0;
+       }
+
+       if (!rd_data) {
+               debug("## No init Ramdisk\n");
+       } else {
+               *rd_start = rd_data;
+               *rd_end = rd_data + rd_len;
+       }
+       debug("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
+             *rd_start, *rd_end);
+
+       return 0;
+}
+
+/**
+ * boot_ramdisk_high - relocate init ramdisk
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @rd_data: ramdisk data start address
+ * @rd_len: ramdisk data length
+ * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
+ *      start address (after possible relocation)
+ * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
+ *      end address (after possible relocation)
+ *
+ * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
+ * variable and if requested ramdisk data is moved to a specified location.
+ *
+ * Initrd_start and initrd_end are set to final (after relocation) ramdisk
+ * start/end addresses if ramdisk image start and len were provided,
+ * otherwise set initrd_start and initrd_end set to zeros.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
+                     ulong *initrd_start, ulong *initrd_end)
+{
+       char    *s;
+       ulong   initrd_high;
+       int     initrd_copy_to_ram = 1;
+
+       s = env_get("initrd_high");
+       if (s) {
+               /* a value of "no" or a similar string will act like 0,
+                * turning the "load high" feature off. This is intentional.
+                */
+               initrd_high = hextoul(s, NULL);
+               if (initrd_high == ~0)
+                       initrd_copy_to_ram = 0;
+       } else {
+               initrd_high = env_get_bootm_mapsize() + env_get_bootm_low();
+       }
+
+       debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
+             initrd_high, initrd_copy_to_ram);
+
+       if (rd_data) {
+               if (!initrd_copy_to_ram) {      /* zero-copy ramdisk support */
+                       debug("   in-place initrd\n");
+                       *initrd_start = rd_data;
+                       *initrd_end = rd_data + rd_len;
+                       lmb_reserve(lmb, rd_data, rd_len);
+               } else {
+                       if (initrd_high)
+                               *initrd_start = (ulong)lmb_alloc_base(lmb,
+                                               rd_len, 0x1000, initrd_high);
+                       else
+                               *initrd_start = (ulong)lmb_alloc(lmb, rd_len,
+                                                                0x1000);
+
+                       if (*initrd_start == 0) {
+                               puts("ramdisk - allocation error\n");
+                               goto error;
+                       }
+                       bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
+
+                       *initrd_end = *initrd_start + rd_len;
+                       printf("   Loading Ramdisk to %08lx, end %08lx ... ",
+                              *initrd_start, *initrd_end);
+
+                       memmove_wd((void *)*initrd_start,
+                                  (void *)rd_data, rd_len, CHUNKSZ);
+
+                       /*
+                        * Ensure the image is flushed to memory to handle
+                        * AMP boot scenarios in which we might not be
+                        * HW cache coherent
+                        */
+                       if (IS_ENABLED(CONFIG_MP)) {
+                               flush_cache((unsigned long)*initrd_start,
+                                           ALIGN(rd_len, ARCH_DMA_MINALIGN));
+                       }
+                       puts("OK\n");
+               }
+       } else {
+               *initrd_start = 0;
+               *initrd_end = 0;
+       }
+       debug("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
+             *initrd_start, *initrd_end);
+
+       return 0;
+
+error:
+       return -1;
+}
+
+int boot_get_setup(bootm_headers_t *images, u8 arch,
+                  ulong *setup_start, ulong *setup_len)
+{
+       if (!CONFIG_IS_ENABLED(FIT))
+               return -ENOENT;
+
+       return boot_get_setup_fit(images, arch, setup_start, setup_len);
+}
+
+int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images,
+                 u8 arch, const ulong *ld_start, ulong * const ld_len)
+{
+       ulong tmp_img_addr, img_data, img_len;
+       void *buf;
+       int conf_noffset;
+       int fit_img_result;
+       const char *uname, *name;
+       int err;
+       int devnum = 0; /* TODO support multi fpga platforms */
+
+       if (!IS_ENABLED(CONFIG_FPGA))
+               return -ENOSYS;
+
+       /* Check to see if the images struct has a FIT configuration */
+       if (!genimg_has_config(images)) {
+               debug("## FIT configuration was not specified\n");
+               return 0;
+       }
+
+       /*
+        * Obtain the os FIT header from the images struct
+        */
+       tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
+       buf = map_sysmem(tmp_img_addr, 0);
+       /*
+        * Check image type. For FIT images get FIT node
+        * and attempt to locate a generic binary.
+        */
+       switch (genimg_get_format(buf)) {
+       case IMAGE_FORMAT_FIT:
+               conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
+
+               uname = fdt_stringlist_get(buf, conf_noffset, FIT_FPGA_PROP, 0,
+                                          NULL);
+               if (!uname) {
+                       debug("## FPGA image is not specified\n");
+                       return 0;
+               }
+               fit_img_result = fit_image_load(images,
+                                               tmp_img_addr,
+                                               (const char **)&uname,
+                                               &images->fit_uname_cfg,
+                                               arch,
+                                               IH_TYPE_FPGA,
+                                               BOOTSTAGE_ID_FPGA_INIT,
+                                               FIT_LOAD_OPTIONAL_NON_ZERO,
+                                               &img_data, &img_len);
+
+               debug("FPGA image (%s) loaded to 0x%lx/size 0x%lx\n",
+                     uname, img_data, img_len);
+
+               if (fit_img_result < 0) {
+                       /* Something went wrong! */
+                       return fit_img_result;
+               }
+
+               if (!fpga_is_partial_data(devnum, img_len)) {
+                       name = "full";
+                       err = fpga_loadbitstream(devnum, (char *)img_data,
+                                                img_len, BIT_FULL);
+                       if (err)
+                               err = fpga_load(devnum, (const void *)img_data,
+                                               img_len, BIT_FULL);
+               } else {
+                       name = "partial";
+                       err = fpga_loadbitstream(devnum, (char *)img_data,
+                                                img_len, BIT_PARTIAL);
+                       if (err)
+                               err = fpga_load(devnum, (const void *)img_data,
+                                               img_len, BIT_PARTIAL);
+               }
+
+               if (err)
+                       return err;
+
+               printf("   Programming %s bitstream... OK\n", name);
+               break;
+       default:
+               printf("The given image format is not supported (corrupt?)\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+static void fit_loadable_process(u8 img_type,
+                                ulong img_data,
+                                ulong img_len)
+{
+       int i;
+       const unsigned int count =
+                       ll_entry_count(struct fit_loadable_tbl, fit_loadable);
+       struct fit_loadable_tbl *fit_loadable_handler =
+                       ll_entry_start(struct fit_loadable_tbl, fit_loadable);
+       /* For each loadable handler */
+       for (i = 0; i < count; i++, fit_loadable_handler++)
+               /* matching this type */
+               if (fit_loadable_handler->type == img_type)
+                       /* call that handler with this image data */
+                       fit_loadable_handler->handler(img_data, img_len);
+}
+
+int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images,
+                     u8 arch, const ulong *ld_start, ulong * const ld_len)
+{
+       /*
+        * These variables are used to hold the current image location
+        * in system memory.
+        */
+       ulong tmp_img_addr;
+       /*
+        * These two variables are requirements for fit_image_load, but
+        * their values are not used
+        */
+       ulong img_data, img_len;
+       void *buf;
+       int loadables_index;
+       int conf_noffset;
+       int fit_img_result;
+       const char *uname;
+       u8 img_type;
+
+       /* Check to see if the images struct has a FIT configuration */
+       if (!genimg_has_config(images)) {
+               debug("## FIT configuration was not specified\n");
+               return 0;
+       }
+
+       /*
+        * Obtain the os FIT header from the images struct
+        */
+       tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
+       buf = map_sysmem(tmp_img_addr, 0);
+       /*
+        * Check image type. For FIT images get FIT node
+        * and attempt to locate a generic binary.
+        */
+       switch (genimg_get_format(buf)) {
+       case IMAGE_FORMAT_FIT:
+               conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
+
+               for (loadables_index = 0;
+                    uname = fdt_stringlist_get(buf, conf_noffset,
+                                               FIT_LOADABLE_PROP,
+                                               loadables_index, NULL), uname;
+                    loadables_index++) {
+                       fit_img_result = fit_image_load(images, tmp_img_addr,
+                                                       &uname,
+                                                       &images->fit_uname_cfg,
+                                                       arch, IH_TYPE_LOADABLE,
+                                                       BOOTSTAGE_ID_FIT_LOADABLE_START,
+                                                       FIT_LOAD_OPTIONAL_NON_ZERO,
+                                                       &img_data, &img_len);
+                       if (fit_img_result < 0) {
+                               /* Something went wrong! */
+                               return fit_img_result;
+                       }
+
+                       fit_img_result = fit_image_get_node(buf, uname);
+                       if (fit_img_result < 0) {
+                               /* Something went wrong! */
+                               return fit_img_result;
+                       }
+                       fit_img_result = fit_image_get_type(buf,
+                                                           fit_img_result,
+                                                           &img_type);
+                       if (fit_img_result < 0) {
+                               /* Something went wrong! */
+                               return fit_img_result;
+                       }
+
+                       fit_loadable_process(img_type, img_data, img_len);
+               }
+               break;
+       default:
+               printf("The given image format is not supported (corrupt?)\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+/**
+ * boot_get_cmdline - allocate and initialize kernel cmdline
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @cmd_start: pointer to a ulong variable, will hold cmdline start
+ * @cmd_end: pointer to a ulong variable, will hold cmdline end
+ *
+ * boot_get_cmdline() allocates space for kernel command line below
+ * BOOTMAPSZ + env_get_bootm_low() address. If "bootargs" U-Boot environment
+ * variable is present its contents is copied to allocated kernel
+ * command line.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
+{
+       char *cmdline;
+       char *s;
+
+       cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
+                               env_get_bootm_mapsize() + env_get_bootm_low());
+       if (!cmdline)
+               return -1;
+
+       s = env_get("bootargs");
+       if (!s)
+               s = "";
+
+       strcpy(cmdline, s);
+
+       *cmd_start = (ulong)cmdline;
+       *cmd_end = *cmd_start + strlen(cmdline);
+
+       debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
+
+       return 0;
+}
+
+/**
+ * boot_get_kbd - allocate and initialize kernel copy of board info
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @kbd: double pointer to board info data
+ *
+ * boot_get_kbd() allocates space for kernel copy of board info data below
+ * BOOTMAPSZ + env_get_bootm_low() address and kernel board info is initialized
+ * with the current u-boot board info data.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd)
+{
+       *kbd = (struct bd_info *)(ulong)lmb_alloc_base(lmb,
+                                                      sizeof(struct bd_info),
+                                                      0xf,
+                                                      env_get_bootm_mapsize() +
+                                                      env_get_bootm_low());
+       if (!*kbd)
+               return -1;
+
+       **kbd = *gd->bd;
+
+       debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
+
+#if defined(DEBUG)
+       if (IS_ENABLED(CONFIG_CMD_BDI))
+               do_bdinfo(NULL, 0, 0, NULL);
+#endif
+
+       return 0;
+}
+
+int image_setup_linux(bootm_headers_t *images)
+{
+       ulong of_size = images->ft_len;
+       char **of_flat_tree = &images->ft_addr;
+       struct lmb *lmb = &images->lmb;
+       int ret;
+
+       if (CONFIG_IS_ENABLED(OF_LIBFDT))
+               boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+
+       if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) {
+               ret = boot_get_cmdline(lmb, &images->cmdline_start,
+                                      &images->cmdline_end);
+               if (ret) {
+                       puts("ERROR with allocation of cmdline\n");
+                       return ret;
+               }
+       }
+
+       if (CONFIG_IS_ENABLED(OF_LIBFDT)) {
+               ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
+               if (ret)
+                       return ret;
+       }
+
+       if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) {
+               ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+void genimg_print_size(uint32_t size)
+{
+       printf("%d Bytes = ", size);
+       print_size(size, "\n");
+}
+
+void genimg_print_time(time_t timestamp)
+{
+       struct rtc_time tm;
+
+       rtc_to_tm(timestamp, &tm);
+       printf("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
+              tm.tm_year, tm.tm_mon, tm.tm_mday,
+              tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
diff --git a/boot/image-cipher.c b/boot/image-cipher.c
new file mode 100644 (file)
index 0000000..b906148
--- /dev/null
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019, Softathome
+ */
+
+#ifdef USE_HOSTCC
+#include "mkimage.h"
+#include <time.h>
+#else
+#include <common.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* !USE_HOSdTCC*/
+#include <image.h>
+#include <uboot_aes.h>
+#include <u-boot/aes.h>
+
+struct cipher_algo cipher_algos[] = {
+       {
+               .name = "aes128",
+               .key_len = AES128_KEY_LENGTH,
+               .iv_len  = AES_BLOCK_LENGTH,
+#if IMAGE_ENABLE_ENCRYPT
+               .calculate_type = EVP_aes_128_cbc,
+#endif
+               .encrypt = image_aes_encrypt,
+               .decrypt = image_aes_decrypt,
+               .add_cipher_data = image_aes_add_cipher_data
+       },
+       {
+               .name = "aes192",
+               .key_len = AES192_KEY_LENGTH,
+               .iv_len  = AES_BLOCK_LENGTH,
+#if IMAGE_ENABLE_ENCRYPT
+               .calculate_type = EVP_aes_192_cbc,
+#endif
+               .encrypt = image_aes_encrypt,
+               .decrypt = image_aes_decrypt,
+               .add_cipher_data = image_aes_add_cipher_data
+       },
+       {
+               .name = "aes256",
+               .key_len = AES256_KEY_LENGTH,
+               .iv_len  = AES_BLOCK_LENGTH,
+#if IMAGE_ENABLE_ENCRYPT
+               .calculate_type = EVP_aes_256_cbc,
+#endif
+               .encrypt = image_aes_encrypt,
+               .decrypt = image_aes_decrypt,
+               .add_cipher_data = image_aes_add_cipher_data
+       }
+};
+
+struct cipher_algo *image_get_cipher_algo(const char *full_name)
+{
+       int i;
+       const char *name;
+
+       for (i = 0; i < ARRAY_SIZE(cipher_algos); i++) {
+               name = cipher_algos[i].name;
+               if (!strncmp(name, full_name, strlen(name)))
+                       return &cipher_algos[i];
+       }
+
+       return NULL;
+}
+
+static int fit_image_setup_decrypt(struct image_cipher_info *info,
+                                  const void *fit, int image_noffset,
+                                  int cipher_noffset)
+{
+       const void *fdt = gd_fdt_blob();
+       const char *node_name;
+       char node_path[128];
+       int noffset;
+       char *algo_name;
+       int ret;
+
+       node_name = fit_get_name(fit, image_noffset, NULL);
+       if (!node_name) {
+               printf("Can't get node name\n");
+               return -1;
+       }
+
+       if (fit_image_cipher_get_algo(fit, cipher_noffset, &algo_name)) {
+               printf("Can't get algo name for cipher '%s' in image '%s'\n",
+                      node_name, node_name);
+               return -1;
+       }
+
+       info->keyname = fdt_getprop(fit, cipher_noffset, FIT_KEY_HINT, NULL);
+       if (!info->keyname) {
+               printf("Can't get key name\n");
+               return -1;
+       }
+
+       info->iv = fdt_getprop(fit, cipher_noffset, "iv", NULL);
+       info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL);
+
+       if (!info->iv && !info->ivname) {
+               printf("Can't get IV or IV name\n");
+               return -1;
+       }
+
+       info->fit = fit;
+       info->node_noffset = image_noffset;
+       info->name = algo_name;
+       info->cipher = image_get_cipher_algo(algo_name);
+       if (!info->cipher) {
+               printf("Can't get cipher\n");
+               return -1;
+       }
+
+       ret = fit_image_get_data_size_unciphered(fit, image_noffset,
+                                                &info->size_unciphered);
+       if (ret) {
+               printf("Can't get size of unciphered data\n");
+               return -1;
+       }
+
+       /*
+        * Search the cipher node in the u-boot fdt
+        * the path should be: /cipher/key-<algo>-<key>-<iv>
+        */
+       if (info->ivname)
+               snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s",
+                        FIT_CIPHER_NODENAME, algo_name, info->keyname, info->ivname);
+       else
+               snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s",
+                        FIT_CIPHER_NODENAME, algo_name, info->keyname);
+
+       noffset = fdt_path_offset(fdt, node_path);
+       if (noffset < 0) {
+               printf("Can't found cipher node offset\n");
+               return -1;
+       }
+
+       /* read key */
+       info->key = fdt_getprop(fdt, noffset, "key", NULL);
+       if (!info->key) {
+               printf("Can't get key in cipher node '%s'\n", node_path);
+               return -1;
+       }
+
+       /* read iv */
+       if (!info->iv) {
+               info->iv = fdt_getprop(fdt, noffset, "iv", NULL);
+               if (!info->iv) {
+                       printf("Can't get IV in cipher node '%s'\n", node_path);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+int fit_image_decrypt_data(const void *fit,
+                          int image_noffset, int cipher_noffset,
+                          const void *data_ciphered, size_t size_ciphered,
+                          void **data_unciphered, size_t *size_unciphered)
+{
+       struct image_cipher_info info;
+       int ret;
+
+       ret = fit_image_setup_decrypt(&info, fit, image_noffset,
+                                     cipher_noffset);
+       if (ret < 0)
+               goto out;
+
+       ret = info.cipher->decrypt(&info, data_ciphered, size_ciphered,
+                                  data_unciphered, size_unciphered);
+
+ out:
+       return ret;
+}
diff --git a/boot/image-fdt.c b/boot/image-fdt.c
new file mode 100644 (file)
index 0000000..7aad6d5
--- /dev/null
@@ -0,0 +1,666 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <fdt_support.h>
+#include <fdtdec.h>
+#include <env.h>
+#include <errno.h>
+#include <image.h>
+#include <lmb.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <linux/libfdt.h>
+#include <mapmem.h>
+#include <asm/io.h>
+#include <tee/optee.h>
+
+#ifndef CONFIG_SYS_FDT_PAD
+#define CONFIG_SYS_FDT_PAD 0x3000
+#endif
+
+/* adding a ramdisk needs 0x44 bytes in version 2008.10 */
+#define FDT_RAMDISK_OVERHEAD   0x80
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void fdt_error(const char *msg)
+{
+       puts("ERROR: ");
+       puts(msg);
+       puts(" - must RESET the board to recover.\n");
+}
+
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
+static const image_header_t *image_get_fdt(ulong fdt_addr)
+{
+       const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0);
+
+       image_print_contents(fdt_hdr);
+
+       puts("   Verifying Checksum ... ");
+       if (!image_check_hcrc(fdt_hdr)) {
+               fdt_error("fdt header checksum invalid");
+               return NULL;
+       }
+
+       if (!image_check_dcrc(fdt_hdr)) {
+               fdt_error("fdt checksum invalid");
+               return NULL;
+       }
+       puts("OK\n");
+
+       if (!image_check_type(fdt_hdr, IH_TYPE_FLATDT)) {
+               fdt_error("uImage is not a fdt");
+               return NULL;
+       }
+       if (image_get_comp(fdt_hdr) != IH_COMP_NONE) {
+               fdt_error("uImage is compressed");
+               return NULL;
+       }
+       if (fdt_check_header((void *)image_get_data(fdt_hdr)) != 0) {
+               fdt_error("uImage data is not a fdt");
+               return NULL;
+       }
+       return fdt_hdr;
+}
+#endif
+
+static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
+                                   uint64_t size, enum lmb_flags flags)
+{
+       long ret;
+
+       ret = lmb_reserve_flags(lmb, addr, size, flags);
+       if (ret >= 0) {
+               debug("   reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
+                     (unsigned long long)addr,
+                     (unsigned long long)size, flags);
+       } else {
+               puts("ERROR: reserving fdt memory region failed ");
+               printf("(addr=%llx size=%llx flags=%x)\n",
+                      (unsigned long long)addr,
+                      (unsigned long long)size, flags);
+       }
+}
+
+/**
+ * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
+ * sections as unusable
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @fdt_blob: pointer to fdt blob base address
+ *
+ * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block.
+ * Adding the memreserve regions prevents u-boot from using them to store the
+ * initrd or the fdt blob.
+ */
+void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
+{
+       uint64_t addr, size;
+       int i, total, ret;
+       int nodeoffset, subnode;
+       struct fdt_resource res;
+       enum lmb_flags flags;
+
+       if (fdt_check_header(fdt_blob) != 0)
+               return;
+
+       /* process memreserve sections */
+       total = fdt_num_mem_rsv(fdt_blob);
+       for (i = 0; i < total; i++) {
+               if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
+                       continue;
+               boot_fdt_reserve_region(lmb, addr, size, LMB_NONE);
+       }
+
+       /* process reserved-memory */
+       nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory");
+       if (nodeoffset >= 0) {
+               subnode = fdt_first_subnode(fdt_blob, nodeoffset);
+               while (subnode >= 0) {
+                       /* check if this subnode has a reg property */
+                       ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
+                                              &res);
+                       if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) {
+                               flags = LMB_NONE;
+                               if (fdtdec_get_bool(fdt_blob, subnode,
+                                                   "no-map"))
+                                       flags = LMB_NOMAP;
+                               addr = res.start;
+                               size = res.end - res.start + 1;
+                               boot_fdt_reserve_region(lmb, addr, size, flags);
+                       }
+
+                       subnode = fdt_next_subnode(fdt_blob, subnode);
+               }
+       }
+}
+
+/**
+ * boot_relocate_fdt - relocate flat device tree
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @of_flat_tree: pointer to a char* variable, will hold fdt start address
+ * @of_size: pointer to a ulong variable, will hold fdt length
+ *
+ * boot_relocate_fdt() allocates a region of memory within the bootmap and
+ * relocates the of_flat_tree into that region, even if the fdt is already in
+ * the bootmap.  It also expands the size of the fdt by CONFIG_SYS_FDT_PAD
+ * bytes.
+ *
+ * of_flat_tree and of_size are set to final (after relocation) values
+ *
+ * returns:
+ *      0 - success
+ *      1 - failure
+ */
+int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
+{
+       void    *fdt_blob = *of_flat_tree;
+       void    *of_start = NULL;
+       char    *fdt_high;
+       ulong   of_len = 0;
+       int     err;
+       int     disable_relocation = 0;
+
+       /* nothing to do */
+       if (*of_size == 0)
+               return 0;
+
+       if (fdt_check_header(fdt_blob) != 0) {
+               fdt_error("image is not a fdt");
+               goto error;
+       }
+
+       /* position on a 4K boundary before the alloc_current */
+       /* Pad the FDT by a specified amount */
+       of_len = *of_size + CONFIG_SYS_FDT_PAD;
+
+       /* If fdt_high is set use it to select the relocation address */
+       fdt_high = env_get("fdt_high");
+       if (fdt_high) {
+               void *desired_addr = (void *)hextoul(fdt_high, NULL);
+
+               if (((ulong) desired_addr) == ~0UL) {
+                       /* All ones means use fdt in place */
+                       of_start = fdt_blob;
+                       lmb_reserve(lmb, (ulong)of_start, of_len);
+                       disable_relocation = 1;
+               } else if (desired_addr) {
+                       of_start =
+                           (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
+                                                          (ulong)desired_addr);
+                       if (of_start == NULL) {
+                               puts("Failed using fdt_high value for Device Tree");
+                               goto error;
+                       }
+               } else {
+                       of_start =
+                           (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000);
+               }
+       } else {
+               of_start =
+                   (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
+                                                  env_get_bootm_mapsize()
+                                                  + env_get_bootm_low());
+       }
+
+       if (of_start == NULL) {
+               puts("device tree - allocation error\n");
+               goto error;
+       }
+
+       if (disable_relocation) {
+               /*
+                * We assume there is space after the existing fdt to use
+                * for padding
+                */
+               fdt_set_totalsize(of_start, of_len);
+               printf("   Using Device Tree in place at %p, end %p\n",
+                      of_start, of_start + of_len - 1);
+       } else {
+               debug("## device tree at %p ... %p (len=%ld [0x%lX])\n",
+                     fdt_blob, fdt_blob + *of_size - 1, of_len, of_len);
+
+               printf("   Loading Device Tree to %p, end %p ... ",
+                      of_start, of_start + of_len - 1);
+
+               err = fdt_open_into(fdt_blob, of_start, of_len);
+               if (err != 0) {
+                       fdt_error("fdt move failed");
+                       goto error;
+               }
+               puts("OK\n");
+       }
+
+       *of_flat_tree = of_start;
+       *of_size = of_len;
+
+       if (CONFIG_IS_ENABLED(CMD_FDT))
+               set_working_fdt_addr(map_to_sysmem(*of_flat_tree));
+       return 0;
+
+error:
+       return 1;
+}
+
+/**
+ * select_fdt() - Select and locate the FDT to use
+ *
+ * @images: pointer to the bootm images structure
+ * @select: name of FDT to select, or NULL for any
+ * @arch: expected FDT architecture
+ * @fdt_addrp: pointer to a ulong variable, will hold FDT pointer
+ * @return 0 if OK, -ENOPKG if no FDT (but an error should not be reported),
+ *     other -ve value on other error
+ */
+
+static int select_fdt(bootm_headers_t *images, const char *select, u8 arch,
+                     ulong *fdt_addrp)
+{
+       const char *buf;
+       ulong fdt_addr;
+
+#if CONFIG_IS_ENABLED(FIT)
+       const char *fit_uname_config = images->fit_uname_cfg;
+       const char *fit_uname_fdt = NULL;
+       ulong default_addr;
+       int fdt_noffset;
+
+       if (select) {
+                       /*
+                        * If the FDT blob comes from the FIT image and the
+                        * FIT image address is omitted in the command line
+                        * argument, try to use ramdisk or os FIT image
+                        * address or default load address.
+                        */
+                       if (images->fit_uname_rd)
+                               default_addr = (ulong)images->fit_hdr_rd;
+                       else if (images->fit_uname_os)
+                               default_addr = (ulong)images->fit_hdr_os;
+                       else
+                               default_addr = image_load_addr;
+
+                       if (fit_parse_conf(select, default_addr, &fdt_addr,
+                                          &fit_uname_config)) {
+                               debug("*  fdt: config '%s' from image at 0x%08lx\n",
+                                     fit_uname_config, fdt_addr);
+                       } else if (fit_parse_subimage(select, default_addr, &fdt_addr,
+                                  &fit_uname_fdt)) {
+                               debug("*  fdt: subimage '%s' from image at 0x%08lx\n",
+                                     fit_uname_fdt, fdt_addr);
+                       } else
+#endif
+               {
+                       fdt_addr = hextoul(select, NULL);
+                       debug("*  fdt: cmdline image address = 0x%08lx\n",
+                             fdt_addr);
+               }
+#if CONFIG_IS_ENABLED(FIT)
+       } else {
+               /* use FIT configuration provided in first bootm
+                * command argument
+                */
+               fdt_addr = map_to_sysmem(images->fit_hdr_os);
+               fdt_noffset = fit_get_node_from_config(images, FIT_FDT_PROP,
+                                                      fdt_addr);
+               if (fdt_noffset == -ENOENT)
+                       return -ENOPKG;
+               else if (fdt_noffset < 0)
+                       return fdt_noffset;
+       }
+#endif
+       debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",
+             fdt_addr);
+
+       /*
+        * Check if there is an FDT image at the
+        * address provided in the second bootm argument
+        * check image type, for FIT images get a FIT node.
+        */
+       buf = map_sysmem(fdt_addr, 0);
+       switch (genimg_get_format(buf)) {
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
+       case IMAGE_FORMAT_LEGACY: {
+                       const image_header_t *fdt_hdr;
+                       ulong load, load_end;
+                       ulong image_start, image_data, image_end;
+
+                       /* verify fdt_addr points to a valid image header */
+                       printf("## Flattened Device Tree from Legacy Image at %08lx\n",
+                              fdt_addr);
+                       fdt_hdr = image_get_fdt(fdt_addr);
+                       if (!fdt_hdr)
+                               return -ENOPKG;
+
+                       /*
+                        * move image data to the load address,
+                        * make sure we don't overwrite initial image
+                        */
+                       image_start = (ulong)fdt_hdr;
+                       image_data = (ulong)image_get_data(fdt_hdr);
+                       image_end = image_get_image_end(fdt_hdr);
+
+                       load = image_get_load(fdt_hdr);
+                       load_end = load + image_get_data_size(fdt_hdr);
+
+                       if (load == image_start ||
+                           load == image_data) {
+                               fdt_addr = load;
+                               break;
+                       }
+
+                       if ((load < image_end) && (load_end > image_start)) {
+                               fdt_error("fdt overwritten");
+                               return -EFAULT;
+                       }
+
+                       debug("   Loading FDT from 0x%08lx to 0x%08lx\n",
+                             image_data, load);
+
+                       memmove((void *)load,
+                               (void *)image_data,
+                               image_get_data_size(fdt_hdr));
+
+                       fdt_addr = load;
+                       break;
+               }
+#endif
+       case IMAGE_FORMAT_FIT:
+               /*
+                * This case will catch both: new uImage format
+                * (libfdt based) and raw FDT blob (also libfdt
+                * based).
+                */
+#if CONFIG_IS_ENABLED(FIT)
+                       /* check FDT blob vs FIT blob */
+                       if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {
+                               ulong load, len;
+
+                               fdt_noffset = boot_get_fdt_fit(images, fdt_addr,
+                                                              &fit_uname_fdt,
+                                                              &fit_uname_config,
+                                                              arch, &load, &len);
+
+                               if (fdt_noffset < 0)
+                                       return -ENOENT;
+
+                               images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
+                               images->fit_uname_fdt = fit_uname_fdt;
+                               images->fit_noffset_fdt = fdt_noffset;
+                               fdt_addr = load;
+
+                               break;
+               } else
+#endif
+               {
+                       /*
+                        * FDT blob
+                        */
+                       debug("*  fdt: raw FDT blob\n");
+                       printf("## Flattened Device Tree blob at %08lx\n",
+                              (long)fdt_addr);
+               }
+               break;
+       default:
+               puts("ERROR: Did not find a cmdline Flattened Device Tree\n");
+               return -ENOENT;
+       }
+       *fdt_addrp = fdt_addr;
+
+       return 0;
+}
+
+/**
+ * boot_get_fdt - main fdt handling routine
+ * @argc: command argument count
+ * @argv: command argument list
+ * @arch: architecture (IH_ARCH_...)
+ * @images: pointer to the bootm images structure
+ * @of_flat_tree: pointer to a char* variable, will hold fdt start address
+ * @of_size: pointer to a ulong variable, will hold fdt length
+ *
+ * boot_get_fdt() is responsible for finding a valid flat device tree image.
+ * Currently supported are the following ramdisk sources:
+ *      - multicomponent kernel/ramdisk image,
+ *      - commandline provided address of decicated ramdisk image.
+ *
+ * returns:
+ *     0, if fdt image was found and valid, or skipped
+ *     of_flat_tree and of_size are set to fdt start address and length if
+ *     fdt image is found and valid
+ *
+ *     1, if fdt image is found but corrupted
+ *     of_flat_tree and of_size are set to 0 if no fdt exists
+ */
+int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
+                bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
+{
+       ulong           img_addr;
+       ulong           fdt_addr;
+       char            *fdt_blob = NULL;
+       void            *buf;
+       const char *select = NULL;
+
+       *of_flat_tree = NULL;
+       *of_size = 0;
+
+       img_addr = (argc == 0) ? image_load_addr : hextoul(argv[0], NULL);
+       buf = map_sysmem(img_addr, 0);
+
+       if (argc > 2)
+               select = argv[2];
+       if (select || genimg_has_config(images)) {
+               int ret;
+
+               ret = select_fdt(images, select, arch, &fdt_addr);
+               if (ret == -ENOPKG)
+                       goto no_fdt;
+               else if (ret)
+                       return 1;
+               printf("   Booting using the fdt blob at %#08lx\n", fdt_addr);
+               fdt_blob = map_sysmem(fdt_addr, 0);
+       } else if (images->legacy_hdr_valid &&
+                       image_check_type(&images->legacy_hdr_os_copy,
+                                        IH_TYPE_MULTI)) {
+               ulong fdt_data, fdt_len;
+
+               /*
+                * Now check if we have a legacy multi-component image,
+                * get second entry data start address and len.
+                */
+               printf("## Flattened Device Tree from multi component Image at %08lX\n",
+                      (ulong)images->legacy_hdr_os);
+
+               image_multi_getimg(images->legacy_hdr_os, 2, &fdt_data,
+                                  &fdt_len);
+               if (fdt_len) {
+                       fdt_blob = (char *)fdt_data;
+                       printf("   Booting using the fdt at 0x%p\n", fdt_blob);
+
+                       if (fdt_check_header(fdt_blob) != 0) {
+                               fdt_error("image is not a fdt");
+                               goto error;
+                       }
+
+                       if (fdt_totalsize(fdt_blob) != fdt_len) {
+                               fdt_error("fdt size != image size");
+                               goto error;
+                       }
+               } else {
+                       debug("## No Flattened Device Tree\n");
+                       goto no_fdt;
+               }
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+       } else if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) {
+               struct andr_img_hdr *hdr = buf;
+               ulong           fdt_data, fdt_len;
+               u32                     fdt_size, dtb_idx;
+               /*
+                * Firstly check if this android boot image has dtb field.
+                */
+               dtb_idx = (u32)env_get_ulong("adtb_idx", 10, 0);
+               if (android_image_get_dtb_by_index((ulong)hdr, dtb_idx, &fdt_addr, &fdt_size)) {
+                       fdt_blob = (char *)map_sysmem(fdt_addr, 0);
+                       if (fdt_check_header(fdt_blob))
+                               goto no_fdt;
+
+                       debug("## Using FDT in Android image dtb area with idx %u\n", dtb_idx);
+               } else if (!android_image_get_second(hdr, &fdt_data, &fdt_len) &&
+                       !fdt_check_header((char *)fdt_data)) {
+                       fdt_blob = (char *)fdt_data;
+                       if (fdt_totalsize(fdt_blob) != fdt_len)
+                               goto error;
+
+                       debug("## Using FDT in Android image second area\n");
+               } else {
+                       fdt_addr = env_get_hex("fdtaddr", 0);
+                       if (!fdt_addr)
+                               goto no_fdt;
+
+                       fdt_blob = map_sysmem(fdt_addr, 0);
+                       if (fdt_check_header(fdt_blob))
+                               goto no_fdt;
+
+                       debug("## Using FDT at ${fdtaddr}=Ox%lx\n", fdt_addr);
+               }
+#endif
+       } else {
+               debug("## No Flattened Device Tree\n");
+               goto no_fdt;
+       }
+
+       *of_flat_tree = fdt_blob;
+       *of_size = fdt_totalsize(fdt_blob);
+       debug("   of_flat_tree at 0x%08lx size 0x%08lx\n",
+             (ulong)*of_flat_tree, *of_size);
+
+       return 0;
+
+no_fdt:
+       debug("Continuing to boot without FDT\n");
+       return 0;
+error:
+       return 1;
+}
+
+/*
+ * Verify the device tree.
+ *
+ * This function is called after all device tree fix-ups have been enacted,
+ * so that the final device tree can be verified.  The definition of "verified"
+ * is up to the specific implementation.  However, it generally means that the
+ * addresses of some of the devices in the device tree are compared with the
+ * actual addresses at which U-Boot has placed them.
+ *
+ * Returns 1 on success, 0 on failure.  If 0 is returned, U-Boot will halt the
+ * boot process.
+ */
+__weak int ft_verify_fdt(void *fdt)
+{
+       return 1;
+}
+
+__weak int arch_fixup_fdt(void *blob)
+{
+       return 0;
+}
+
+int image_setup_libfdt(bootm_headers_t *images, void *blob,
+                      int of_size, struct lmb *lmb)
+{
+       ulong *initrd_start = &images->initrd_start;
+       ulong *initrd_end = &images->initrd_end;
+       int ret = -EPERM;
+       int fdt_ret;
+
+       if (fdt_root(blob) < 0) {
+               printf("ERROR: root node setup failed\n");
+               goto err;
+       }
+       if (fdt_chosen(blob) < 0) {
+               printf("ERROR: /chosen node create failed\n");
+               goto err;
+       }
+       if (arch_fixup_fdt(blob) < 0) {
+               printf("ERROR: arch-specific fdt fixup failed\n");
+               goto err;
+       }
+
+       fdt_ret = optee_copy_fdt_nodes(blob);
+       if (fdt_ret) {
+               printf("ERROR: transfer of optee nodes to new fdt failed: %s\n",
+                      fdt_strerror(fdt_ret));
+               goto err;
+       }
+
+       /* Update ethernet nodes */
+       fdt_fixup_ethernet(blob);
+#if CONFIG_IS_ENABLED(CMD_PSTORE)
+       /* Append PStore configuration */
+       fdt_fixup_pstore(blob);
+#endif
+       if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) {
+               const char *skip_board_fixup;
+
+               skip_board_fixup = env_get("skip_board_fixup");
+               if (skip_board_fixup && ((int)simple_strtol(skip_board_fixup, NULL, 10) == 1)) {
+                       printf("skip board fdt fixup\n");
+               } else {
+                       fdt_ret = ft_board_setup(blob, gd->bd);
+                       if (fdt_ret) {
+                               printf("ERROR: board-specific fdt fixup failed: %s\n",
+                                      fdt_strerror(fdt_ret));
+                               goto err;
+                       }
+               }
+       }
+       if (IS_ENABLED(CONFIG_OF_SYSTEM_SETUP)) {
+               fdt_ret = ft_system_setup(blob, gd->bd);
+               if (fdt_ret) {
+                       printf("ERROR: system-specific fdt fixup failed: %s\n",
+                              fdt_strerror(fdt_ret));
+                       goto err;
+               }
+       }
+
+       /* Delete the old LMB reservation */
+       if (lmb)
+               lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob,
+                        (phys_size_t)fdt_totalsize(blob));
+
+       ret = fdt_shrink_to_minimum(blob, 0);
+       if (ret < 0)
+               goto err;
+       of_size = ret;
+
+       if (*initrd_start && *initrd_end) {
+               of_size += FDT_RAMDISK_OVERHEAD;
+               fdt_set_totalsize(blob, of_size);
+       }
+       /* Create a new LMB reservation */
+       if (lmb)
+               lmb_reserve(lmb, (ulong)blob, of_size);
+
+       fdt_initrd(blob, *initrd_start, *initrd_end);
+       if (!ft_verify_fdt(blob))
+               goto err;
+
+#if defined(CONFIG_ARCH_KEYSTONE)
+       if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))
+               ft_board_setup_ex(blob, gd->bd);
+#endif
+
+       return 0;
+err:
+       printf(" - must RESET the board to recover.\n\n");
+
+       return ret;
+}
diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c
new file mode 100644 (file)
index 0000000..63e5423
--- /dev/null
@@ -0,0 +1,486 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013, Google Inc.
+ */
+
+#ifdef USE_HOSTCC
+#include "mkimage.h"
+#include <time.h>
+#else
+#include <common.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* !USE_HOSTCC*/
+#include <fdt_region.h>
+#include <image.h>
+#include <u-boot/rsa.h>
+#include <u-boot/hash-checksum.h>
+
+#define IMAGE_MAX_HASHED_NODES         100
+
+/**
+ * fit_region_make_list() - Make a list of image regions
+ *
+ * Given a list of fdt_regions, create a list of image_regions. This is a
+ * simple conversion routine since the FDT and image code use different
+ * structures.
+ *
+ * @fit: FIT image
+ * @fdt_regions: Pointer to FDT regions
+ * @count: Number of FDT regions
+ * @region: Pointer to image regions, which must hold @count records. If
+ * region is NULL, then (except for an SPL build) the array will be
+ * allocated.
+ * @return: Pointer to image regions
+ */
+struct image_region *fit_region_make_list(const void *fit,
+                                         struct fdt_region *fdt_regions,
+                                         int count,
+                                         struct image_region *region)
+{
+       int i;
+
+       debug("Hash regions:\n");
+       debug("%10s %10s\n", "Offset", "Size");
+
+       /*
+        * Use malloc() except in SPL (to save code size). In SPL the caller
+        * must allocate the array.
+        */
+       if (!IS_ENABLED(CONFIG_SPL_BUILD) && !region)
+               region = calloc(sizeof(*region), count);
+       if (!region)
+               return NULL;
+       for (i = 0; i < count; i++) {
+               debug("%10x %10x\n", fdt_regions[i].offset,
+                     fdt_regions[i].size);
+               region[i].data = fit + fdt_regions[i].offset;
+               region[i].size = fdt_regions[i].size;
+       }
+
+       return region;
+}
+
+static int fit_image_setup_verify(struct image_sign_info *info,
+                                 const void *fit, int noffset,
+                                 int required_keynode, char **err_msgp)
+{
+       char *algo_name;
+       const char *padding_name;
+
+       if (fdt_totalsize(fit) > CONFIG_VAL(FIT_SIGNATURE_MAX_SIZE)) {
+               *err_msgp = "Total size too large";
+               return 1;
+       }
+       if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
+               *err_msgp = "Can't get hash algo property";
+               return -1;
+       }
+
+       padding_name = fdt_getprop(fit, noffset, "padding", NULL);
+       if (!padding_name)
+               padding_name = RSA_DEFAULT_PADDING_NAME;
+
+       memset(info, '\0', sizeof(*info));
+       info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
+       info->fit = fit;
+       info->node_offset = noffset;
+       info->name = algo_name;
+       info->checksum = image_get_checksum_algo(algo_name);
+       info->crypto = image_get_crypto_algo(algo_name);
+       info->padding = image_get_padding_algo(padding_name);
+       info->fdt_blob = gd_fdt_blob();
+       info->required_keynode = required_keynode;
+       printf("%s:%s", algo_name, info->keyname);
+
+       if (!info->checksum || !info->crypto || !info->padding) {
+               *err_msgp = "Unknown signature algorithm";
+               return -1;
+       }
+
+       return 0;
+}
+
+int fit_image_check_sig(const void *fit, int noffset, const void *data,
+                       size_t size, int required_keynode, char **err_msgp)
+{
+       struct image_sign_info info;
+       struct image_region region;
+       uint8_t *fit_value;
+       int fit_value_len;
+
+       *err_msgp = NULL;
+       if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
+                                  err_msgp))
+               return -1;
+
+       if (fit_image_hash_get_value(fit, noffset, &fit_value,
+                                    &fit_value_len)) {
+               *err_msgp = "Can't get hash value property";
+               return -1;
+       }
+
+       region.data = data;
+       region.size = size;
+
+       if (info.crypto->verify(&info, &region, 1, fit_value, fit_value_len)) {
+               *err_msgp = "Verification failed";
+               return -1;
+       }
+
+       return 0;
+}
+
+static int fit_image_verify_sig(const void *fit, int image_noffset,
+                               const char *data, size_t size,
+                               const void *sig_blob, int sig_offset)
+{
+       int noffset;
+       char *err_msg = "";
+       int verified = 0;
+       int ret;
+
+       /* Process all hash subnodes of the component image node */
+       fdt_for_each_subnode(noffset, fit, image_noffset) {
+               const char *name = fit_get_name(fit, noffset, NULL);
+
+               /*
+                * We don't support this since libfdt considers names with the
+                * name root but different @ suffix to be equal
+                */
+               if (strchr(name, '@')) {
+                       err_msg = "Node name contains @";
+                       goto error;
+               }
+               if (!strncmp(name, FIT_SIG_NODENAME,
+                            strlen(FIT_SIG_NODENAME))) {
+                       ret = fit_image_check_sig(fit, noffset, data,
+                                                 size, -1, &err_msg);
+                       if (ret) {
+                               puts("- ");
+                       } else {
+                               puts("+ ");
+                               verified = 1;
+                               break;
+                       }
+               }
+       }
+
+       if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
+               err_msg = "Corrupted or truncated tree";
+               goto error;
+       }
+
+       return verified ? 0 : -EPERM;
+
+error:
+       printf(" error!\n%s for '%s' hash node in '%s' image node\n",
+              err_msg, fit_get_name(fit, noffset, NULL),
+              fit_get_name(fit, image_noffset, NULL));
+       return -1;
+}
+
+int fit_image_verify_required_sigs(const void *fit, int image_noffset,
+                                  const char *data, size_t size,
+                                  const void *sig_blob, int *no_sigsp)
+{
+       int verify_count = 0;
+       int noffset;
+       int sig_node;
+
+       /* Work out what we need to verify */
+       *no_sigsp = 1;
+       sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
+       if (sig_node < 0) {
+               debug("%s: No signature node found: %s\n", __func__,
+                     fdt_strerror(sig_node));
+               return 0;
+       }
+
+       fdt_for_each_subnode(noffset, sig_blob, sig_node) {
+               const char *required;
+               int ret;
+
+               required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
+                                      NULL);
+               if (!required || strcmp(required, "image"))
+                       continue;
+               ret = fit_image_verify_sig(fit, image_noffset, data, size,
+                                          sig_blob, noffset);
+               if (ret) {
+                       printf("Failed to verify required signature '%s'\n",
+                              fit_get_name(sig_blob, noffset, NULL));
+                       return ret;
+               }
+               verify_count++;
+       }
+
+       if (verify_count)
+               *no_sigsp = 0;
+
+       return 0;
+}
+
+/**
+ * fit_config_check_sig() - Check the signature of a config
+ *
+ * @fit: FIT to check
+ * @noffset: Offset of configuration node (e.g. /configurations/conf-1)
+ * @required_keynode:  Offset in the control FDT of the required key node,
+ *                     if any. If this is given, then the configuration wil not
+ *                     pass verification unless that key is used. If this is
+ *                     -1 then any signature will do.
+ * @conf_noffset: Offset of the configuration subnode being checked (e.g.
+ *      /configurations/conf-1/kernel)
+ * @err_msgp:          In the event of an error, this will be pointed to a
+ *                     help error string to display to the user.
+ * @return 0 if all verified ok, <0 on error
+ */
+static int fit_config_check_sig(const void *fit, int noffset,
+                               int required_keynode, int conf_noffset,
+                               char **err_msgp)
+{
+       static char * const exc_prop[] = {
+               "data",
+               "data-size",
+               "data-position",
+               "data-offset"
+       };
+
+       const char *prop, *end, *name;
+       struct image_sign_info info;
+       const uint32_t *strings;
+       const char *config_name;
+       uint8_t *fit_value;
+       int fit_value_len;
+       bool found_config;
+       int max_regions;
+       int i, prop_len;
+       char path[200];
+       int count;
+
+       config_name = fit_get_name(fit, conf_noffset, NULL);
+       debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(),
+             fit_get_name(fit, noffset, NULL),
+             fit_get_name(gd_fdt_blob(), required_keynode, NULL));
+       *err_msgp = NULL;
+       if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
+                                  err_msgp))
+               return -1;
+
+       if (fit_image_hash_get_value(fit, noffset, &fit_value,
+                                    &fit_value_len)) {
+               *err_msgp = "Can't get hash value property";
+               return -1;
+       }
+
+       /* Count the number of strings in the property */
+       prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len);
+       end = prop ? prop + prop_len : prop;
+       for (name = prop, count = 0; name < end; name++)
+               if (!*name)
+                       count++;
+       if (!count) {
+               *err_msgp = "Can't get hashed-nodes property";
+               return -1;
+       }
+
+       if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') {
+               *err_msgp = "hashed-nodes property must be null-terminated";
+               return -1;
+       }
+
+       /* Add a sanity check here since we are using the stack */
+       if (count > IMAGE_MAX_HASHED_NODES) {
+               *err_msgp = "Number of hashed nodes exceeds maximum";
+               return -1;
+       }
+
+       /* Create a list of node names from those strings */
+       char *node_inc[count];
+
+       debug("Hash nodes (%d):\n", count);
+       found_config = false;
+       for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
+               debug("   '%s'\n", name);
+               node_inc[i] = (char *)name;
+               if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) &&
+                   name[sizeof(FIT_CONFS_PATH) - 1] == '/' &&
+                   !strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) {
+                       debug("      (found config node %s)", config_name);
+                       found_config = true;
+               }
+       }
+       if (!found_config) {
+               *err_msgp = "Selected config not in hashed nodes";
+               return -1;
+       }
+
+       /*
+        * Each node can generate one region for each sub-node. Allow for
+        * 7 sub-nodes (hash-1, signature-1, etc.) and some extra.
+        */
+       max_regions = 20 + count * 7;
+       struct fdt_region fdt_regions[max_regions];
+
+       /* Get a list of regions to hash */
+       count = fdt_find_regions(fit, node_inc, count,
+                                exc_prop, ARRAY_SIZE(exc_prop),
+                                fdt_regions, max_regions - 1,
+                                path, sizeof(path), 0);
+       if (count < 0) {
+               *err_msgp = "Failed to hash configuration";
+               return -1;
+       }
+       if (count == 0) {
+               *err_msgp = "No data to hash";
+               return -1;
+       }
+       if (count >= max_regions - 1) {
+               *err_msgp = "Too many hash regions";
+               return -1;
+       }
+
+       /* Add the strings */
+       strings = fdt_getprop(fit, noffset, "hashed-strings", NULL);
+       if (strings) {
+               /*
+                * The strings region offset must be a static 0x0.
+                * This is set in tool/image-host.c
+                */
+               fdt_regions[count].offset = fdt_off_dt_strings(fit);
+               fdt_regions[count].size = fdt32_to_cpu(strings[1]);
+               count++;
+       }
+
+       /* Allocate the region list on the stack */
+       struct image_region region[count];
+
+       fit_region_make_list(fit, fdt_regions, count, region);
+       if (info.crypto->verify(&info, region, count, fit_value,
+                               fit_value_len)) {
+               *err_msgp = "Verification failed";
+               return -1;
+       }
+
+       return 0;
+}
+
+static int fit_config_verify_sig(const void *fit, int conf_noffset,
+                                const void *sig_blob, int sig_offset)
+{
+       int noffset;
+       char *err_msg = "No 'signature' subnode found";
+       int verified = 0;
+       int ret;
+
+       /* Process all hash subnodes of the component conf node */
+       fdt_for_each_subnode(noffset, fit, conf_noffset) {
+               const char *name = fit_get_name(fit, noffset, NULL);
+
+               if (!strncmp(name, FIT_SIG_NODENAME,
+                            strlen(FIT_SIG_NODENAME))) {
+                       ret = fit_config_check_sig(fit, noffset, sig_offset,
+                                                  conf_noffset, &err_msg);
+                       if (ret) {
+                               puts("- ");
+                       } else {
+                               puts("+ ");
+                               verified = 1;
+                               break;
+                       }
+               }
+       }
+
+       if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
+               err_msg = "Corrupted or truncated tree";
+               goto error;
+       }
+
+       if (verified)
+               return 0;
+
+error:
+       printf(" error!\n%s for '%s' hash node in '%s' config node\n",
+              err_msg, fit_get_name(fit, noffset, NULL),
+              fit_get_name(fit, conf_noffset, NULL));
+       return -EPERM;
+}
+
+static int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
+                                          const void *sig_blob)
+{
+       const char *name = fit_get_name(fit, conf_noffset, NULL);
+       int noffset;
+       int sig_node;
+       int verified = 0;
+       int reqd_sigs = 0;
+       bool reqd_policy_all = true;
+       const char *reqd_mode;
+
+       /*
+        * We don't support this since libfdt considers names with the
+        * name root but different @ suffix to be equal
+        */
+       if (strchr(name, '@')) {
+               printf("Configuration node '%s' contains '@'\n", name);
+               return -EPERM;
+       }
+
+       /* Work out what we need to verify */
+       sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
+       if (sig_node < 0) {
+               debug("%s: No signature node found: %s\n", __func__,
+                     fdt_strerror(sig_node));
+               return 0;
+       }
+
+       /* Get required-mode policy property from DTB */
+       reqd_mode = fdt_getprop(sig_blob, sig_node, "required-mode", NULL);
+       if (reqd_mode && !strcmp(reqd_mode, "any"))
+               reqd_policy_all = false;
+
+       debug("%s: required-mode policy set to '%s'\n", __func__,
+             reqd_policy_all ? "all" : "any");
+
+       fdt_for_each_subnode(noffset, sig_blob, sig_node) {
+               const char *required;
+               int ret;
+
+               required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
+                                      NULL);
+               if (!required || strcmp(required, "conf"))
+                       continue;
+
+               reqd_sigs++;
+
+               ret = fit_config_verify_sig(fit, conf_noffset, sig_blob,
+                                           noffset);
+               if (ret) {
+                       if (reqd_policy_all) {
+                               printf("Failed to verify required signature '%s'\n",
+                                      fit_get_name(sig_blob, noffset, NULL));
+                               return ret;
+                       }
+               } else {
+                       verified++;
+                       if (!reqd_policy_all)
+                               break;
+               }
+       }
+
+       if (reqd_sigs && !verified) {
+               printf("Failed to verify 'any' of the required signature(s)\n");
+               return -EPERM;
+       }
+
+       return 0;
+}
+
+int fit_config_verify(const void *fit, int conf_noffset)
+{
+       return fit_config_verify_required_sigs(fit, conf_noffset,
+                                              gd_fdt_blob());
+}
diff --git a/boot/image-fit.c b/boot/image-fit.c
new file mode 100644 (file)
index 0000000..33b4a46
--- /dev/null
@@ -0,0 +1,2448 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#define LOG_CATEGORY LOGC_BOOT
+
+#ifdef USE_HOSTCC
+#include "mkimage.h"
+#include <time.h>
+#include <linux/libfdt.h>
+#include <u-boot/crc.h>
+#else
+#include <linux/compiler.h>
+#include <linux/sizes.h>
+#include <common.h>
+#include <errno.h>
+#include <log.h>
+#include <mapmem.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#ifdef CONFIG_DM_HASH
+#include <dm.h>
+#include <u-boot/hash.h>
+#endif
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* !USE_HOSTCC*/
+
+#include <bootm.h>
+#include <image.h>
+#include <bootstage.h>
+#include <linux/kconfig.h>
+#include <u-boot/crc.h>
+#include <u-boot/md5.h>
+#include <u-boot/sha1.h>
+#include <u-boot/sha256.h>
+#include <u-boot/sha512.h>
+
+/*****************************************************************************/
+/* New uImage format routines */
+/*****************************************************************************/
+#ifndef USE_HOSTCC
+static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
+               ulong *addr, const char **name)
+{
+       const char *sep;
+
+       *addr = addr_curr;
+       *name = NULL;
+
+       sep = strchr(spec, sepc);
+       if (sep) {
+               if (sep - spec > 0)
+                       *addr = hextoul(spec, NULL);
+
+               *name = sep + 1;
+               return 1;
+       }
+
+       return 0;
+}
+
+/**
+ * fit_parse_conf - parse FIT configuration spec
+ * @spec: input string, containing configuration spec
+ * @add_curr: current image address (to be used as a possible default)
+ * @addr: pointer to a ulong variable, will hold FIT image address of a given
+ * configuration
+ * @conf_name double pointer to a char, will hold pointer to a configuration
+ * unit name
+ *
+ * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
+ * where <addr> is a FIT image address that contains configuration
+ * with a <conf> unit name.
+ *
+ * Address part is optional, and if omitted default add_curr will
+ * be used instead.
+ *
+ * returns:
+ *     1 if spec is a valid configuration string,
+ *     addr and conf_name are set accordingly
+ *     0 otherwise
+ */
+int fit_parse_conf(const char *spec, ulong addr_curr,
+               ulong *addr, const char **conf_name)
+{
+       return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
+}
+
+/**
+ * fit_parse_subimage - parse FIT subimage spec
+ * @spec: input string, containing subimage spec
+ * @add_curr: current image address (to be used as a possible default)
+ * @addr: pointer to a ulong variable, will hold FIT image address of a given
+ * subimage
+ * @image_name: double pointer to a char, will hold pointer to a subimage name
+ *
+ * fit_parse_subimage() expects subimage spec in the form of
+ * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
+ * subimage with a <subimg> unit name.
+ *
+ * Address part is optional, and if omitted default add_curr will
+ * be used instead.
+ *
+ * returns:
+ *     1 if spec is a valid subimage string,
+ *     addr and image_name are set accordingly
+ *     0 otherwise
+ */
+int fit_parse_subimage(const char *spec, ulong addr_curr,
+               ulong *addr, const char **image_name)
+{
+       return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
+}
+#endif /* !USE_HOSTCC */
+
+#ifdef USE_HOSTCC
+/* Host tools use these implementations for Cipher and Signature support */
+static void *host_blob;
+
+void image_set_host_blob(void *blob)
+{
+       host_blob = blob;
+}
+
+void *image_get_host_blob(void)
+{
+       return host_blob;
+}
+#endif /* USE_HOSTCC */
+
+static void fit_get_debug(const void *fit, int noffset,
+               char *prop_name, int err)
+{
+       debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
+             prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
+             fdt_strerror(err));
+}
+
+/**
+ * fit_get_subimage_count - get component (sub-image) count
+ * @fit: pointer to the FIT format image header
+ * @images_noffset: offset of images node
+ *
+ * returns:
+ *     number of image components
+ */
+int fit_get_subimage_count(const void *fit, int images_noffset)
+{
+       int noffset;
+       int ndepth;
+       int count = 0;
+
+       /* Process its subnodes, print out component images details */
+       for (ndepth = 0, count = 0,
+               noffset = fdt_next_node(fit, images_noffset, &ndepth);
+            (noffset >= 0) && (ndepth > 0);
+            noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       count++;
+               }
+       }
+
+       return count;
+}
+
+/**
+ * fit_image_print_data() - prints out the hash node details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the hash node
+ * @p: pointer to prefix string
+ * @type: Type of information to print ("hash" or "sign")
+ *
+ * fit_image_print_data() lists properties for the processed hash node
+ *
+ * This function avoid using puts() since it prints a newline on the host
+ * but does not in U-Boot.
+ *
+ * returns:
+ *     no returned results
+ */
+static void fit_image_print_data(const void *fit, int noffset, const char *p,
+                                const char *type)
+{
+       const char *keyname;
+       uint8_t *value;
+       int value_len;
+       char *algo;
+       const char *padding;
+       bool required;
+       int ret, i;
+
+       debug("%s  %s node:    '%s'\n", p, type,
+             fit_get_name(fit, noffset, NULL));
+       printf("%s  %s algo:    ", p, type);
+       if (fit_image_hash_get_algo(fit, noffset, &algo)) {
+               printf("invalid/unsupported\n");
+               return;
+       }
+       printf("%s", algo);
+       keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
+       required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL;
+       if (keyname)
+               printf(":%s", keyname);
+       if (required)
+               printf(" (required)");
+       printf("\n");
+
+       padding = fdt_getprop(fit, noffset, "padding", NULL);
+       if (padding)
+               printf("%s  %s padding: %s\n", p, type, padding);
+
+       ret = fit_image_hash_get_value(fit, noffset, &value,
+                                      &value_len);
+       printf("%s  %s value:   ", p, type);
+       if (ret) {
+               printf("unavailable\n");
+       } else {
+               for (i = 0; i < value_len; i++)
+                       printf("%02x", value[i]);
+               printf("\n");
+       }
+
+       debug("%s  %s len:     %d\n", p, type, value_len);
+
+       /* Signatures have a time stamp */
+       if (IMAGE_ENABLE_TIMESTAMP && keyname) {
+               time_t timestamp;
+
+               printf("%s  Timestamp:    ", p);
+               if (fit_get_timestamp(fit, noffset, &timestamp))
+                       printf("unavailable\n");
+               else
+                       genimg_print_time(timestamp);
+       }
+}
+
+/**
+ * fit_image_print_verification_data() - prints out the hash/signature details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the hash or signature node
+ * @p: pointer to prefix string
+ *
+ * This lists properties for the processed hash node
+ *
+ * returns:
+ *     no returned results
+ */
+static void fit_image_print_verification_data(const void *fit, int noffset,
+                                             const char *p)
+{
+       const char *name;
+
+       /*
+        * Check subnode name, must be equal to "hash" or "signature".
+        * Multiple hash/signature nodes require unique unit node
+        * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
+        */
+       name = fit_get_name(fit, noffset, NULL);
+       if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
+               fit_image_print_data(fit, noffset, p, "Hash");
+       } else if (!strncmp(name, FIT_SIG_NODENAME,
+                               strlen(FIT_SIG_NODENAME))) {
+               fit_image_print_data(fit, noffset, p, "Sign");
+       }
+}
+
+/**
+ * fit_conf_print - prints out the FIT configuration details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the configuration node
+ * @p: pointer to prefix string
+ *
+ * fit_conf_print() lists all mandatory properties for the processed
+ * configuration node.
+ *
+ * returns:
+ *     no returned results
+ */
+static void fit_conf_print(const void *fit, int noffset, const char *p)
+{
+       char *desc;
+       const char *uname;
+       int ret;
+       int fdt_index, loadables_index;
+       int ndepth;
+
+       /* Mandatory properties */
+       ret = fit_get_desc(fit, noffset, &desc);
+       printf("%s  Description:  ", p);
+       if (ret)
+               printf("unavailable\n");
+       else
+               printf("%s\n", desc);
+
+       uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
+       printf("%s  Kernel:       ", p);
+       if (!uname)
+               printf("unavailable\n");
+       else
+               printf("%s\n", uname);
+
+       /* Optional properties */
+       uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
+       if (uname)
+               printf("%s  Init Ramdisk: %s\n", p, uname);
+
+       uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL);
+       if (uname)
+               printf("%s  Firmware:     %s\n", p, uname);
+
+       for (fdt_index = 0;
+            uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
+                                       fdt_index, NULL), uname;
+            fdt_index++) {
+               if (fdt_index == 0)
+                       printf("%s  FDT:          ", p);
+               else
+                       printf("%s                ", p);
+               printf("%s\n", uname);
+       }
+
+       uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
+       if (uname)
+               printf("%s  FPGA:         %s\n", p, uname);
+
+       /* Print out all of the specified loadables */
+       for (loadables_index = 0;
+            uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
+                                       loadables_index, NULL), uname;
+            loadables_index++) {
+               if (loadables_index == 0) {
+                       printf("%s  Loadables:    ", p);
+               } else {
+                       printf("%s                ", p);
+               }
+               printf("%s\n", uname);
+       }
+
+       /* Process all hash subnodes of the component configuration node */
+       for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth);
+            (noffset >= 0) && (ndepth > 0);
+            noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       /* Direct child node of the component configuration node */
+                       fit_image_print_verification_data(fit, noffset, p);
+               }
+       }
+}
+
+/**
+ * fit_print_contents - prints out the contents of the FIT format image
+ * @fit: pointer to the FIT format image header
+ * @p: pointer to prefix string
+ *
+ * fit_print_contents() formats a multi line FIT image contents description.
+ * The routine prints out FIT image properties (root node level) followed by
+ * the details of each component image.
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_print_contents(const void *fit)
+{
+       char *desc;
+       char *uname;
+       int images_noffset;
+       int confs_noffset;
+       int noffset;
+       int ndepth;
+       int count = 0;
+       int ret;
+       const char *p;
+       time_t timestamp;
+
+       if (!CONFIG_IS_ENABLED(FIT_PRINT))
+               return;
+
+       /* Indent string is defined in header image.h */
+       p = IMAGE_INDENT_STRING;
+
+       /* Root node properties */
+       ret = fit_get_desc(fit, 0, &desc);
+       printf("%sFIT description: ", p);
+       if (ret)
+               printf("unavailable\n");
+       else
+               printf("%s\n", desc);
+
+       if (IMAGE_ENABLE_TIMESTAMP) {
+               ret = fit_get_timestamp(fit, 0, &timestamp);
+               printf("%sCreated:         ", p);
+               if (ret)
+                       printf("unavailable\n");
+               else
+                       genimg_print_time(timestamp);
+       }
+
+       /* Find images parent node offset */
+       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (images_noffset < 0) {
+               printf("Can't find images parent node '%s' (%s)\n",
+                      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+               return;
+       }
+
+       /* Process its subnodes, print out component images details */
+       for (ndepth = 0, count = 0,
+               noffset = fdt_next_node(fit, images_noffset, &ndepth);
+            (noffset >= 0) && (ndepth > 0);
+            noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       /*
+                        * Direct child node of the images parent node,
+                        * i.e. component image node.
+                        */
+                       printf("%s Image %u (%s)\n", p, count++,
+                              fit_get_name(fit, noffset, NULL));
+
+                       fit_image_print(fit, noffset, p);
+               }
+       }
+
+       /* Find configurations parent node offset */
+       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
+       if (confs_noffset < 0) {
+               debug("Can't get configurations parent node '%s' (%s)\n",
+                     FIT_CONFS_PATH, fdt_strerror(confs_noffset));
+               return;
+       }
+
+       /* get default configuration unit name from default property */
+       uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
+       if (uname)
+               printf("%s Default Configuration: '%s'\n", p, uname);
+
+       /* Process its subnodes, print out configurations details */
+       for (ndepth = 0, count = 0,
+               noffset = fdt_next_node(fit, confs_noffset, &ndepth);
+            (noffset >= 0) && (ndepth > 0);
+            noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       /*
+                        * Direct child node of the configurations parent node,
+                        * i.e. configuration node.
+                        */
+                       printf("%s Configuration %u (%s)\n", p, count++,
+                              fit_get_name(fit, noffset, NULL));
+
+                       fit_conf_print(fit, noffset, p);
+               }
+       }
+}
+
+/**
+ * fit_image_print - prints out the FIT component image details
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: offset of the component image node
+ * @p: pointer to prefix string
+ *
+ * fit_image_print() lists all mandatory properties for the processed component
+ * image. If present, hash nodes are printed out as well. Load
+ * address for images of type firmware is also printed out. Since the load
+ * address is not mandatory for firmware images, it will be output as
+ * "unavailable" when not present.
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_image_print(const void *fit, int image_noffset, const char *p)
+{
+       char *desc;
+       uint8_t type, arch, os, comp;
+       size_t size;
+       ulong load, entry;
+       const void *data;
+       int noffset;
+       int ndepth;
+       int ret;
+
+       if (!CONFIG_IS_ENABLED(FIT_PRINT))
+               return;
+
+       /* Mandatory properties */
+       ret = fit_get_desc(fit, image_noffset, &desc);
+       printf("%s  Description:  ", p);
+       if (ret)
+               printf("unavailable\n");
+       else
+               printf("%s\n", desc);
+
+       if (IMAGE_ENABLE_TIMESTAMP) {
+               time_t timestamp;
+
+               ret = fit_get_timestamp(fit, 0, &timestamp);
+               printf("%s  Created:      ", p);
+               if (ret)
+                       printf("unavailable\n");
+               else
+                       genimg_print_time(timestamp);
+       }
+
+       fit_image_get_type(fit, image_noffset, &type);
+       printf("%s  Type:         %s\n", p, genimg_get_type_name(type));
+
+       fit_image_get_comp(fit, image_noffset, &comp);
+       printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp));
+
+       ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
+
+       if (!tools_build()) {
+               printf("%s  Data Start:   ", p);
+               if (ret) {
+                       printf("unavailable\n");
+               } else {
+                       void *vdata = (void *)data;
+
+                       printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
+               }
+       }
+
+       printf("%s  Data Size:    ", p);
+       if (ret)
+               printf("unavailable\n");
+       else
+               genimg_print_size(size);
+
+       /* Remaining, type dependent properties */
+       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
+           (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
+           (type == IH_TYPE_FLATDT)) {
+               fit_image_get_arch(fit, image_noffset, &arch);
+               printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch));
+       }
+
+       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK) ||
+           (type == IH_TYPE_FIRMWARE)) {
+               fit_image_get_os(fit, image_noffset, &os);
+               printf("%s  OS:           %s\n", p, genimg_get_os_name(os));
+       }
+
+       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
+           (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
+           (type == IH_TYPE_FPGA)) {
+               ret = fit_image_get_load(fit, image_noffset, &load);
+               printf("%s  Load Address: ", p);
+               if (ret)
+                       printf("unavailable\n");
+               else
+                       printf("0x%08lx\n", load);
+       }
+
+       /* optional load address for FDT */
+       if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
+               printf("%s  Load Address: 0x%08lx\n", p, load);
+
+       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
+           (type == IH_TYPE_RAMDISK)) {
+               ret = fit_image_get_entry(fit, image_noffset, &entry);
+               printf("%s  Entry Point:  ", p);
+               if (ret)
+                       printf("unavailable\n");
+               else
+                       printf("0x%08lx\n", entry);
+       }
+
+       /* Process all hash subnodes of the component image node */
+       for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
+            (noffset >= 0) && (ndepth > 0);
+            noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       /* Direct child node of the component image node */
+                       fit_image_print_verification_data(fit, noffset, p);
+               }
+       }
+}
+
+/**
+ * fit_get_desc - get node description property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @desc: double pointer to the char, will hold pointer to the description
+ *
+ * fit_get_desc() reads description property from a given node, if
+ * description is found pointer to it is returned in third call argument.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_get_desc(const void *fit, int noffset, char **desc)
+{
+       int len;
+
+       *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
+       if (*desc == NULL) {
+               fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * fit_get_timestamp - get node timestamp property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @timestamp: pointer to the time_t, will hold read timestamp
+ *
+ * fit_get_timestamp() reads timestamp property from given node, if timestamp
+ * is found and has a correct size its value is returned in third call
+ * argument.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on property read failure
+ *     -2, on wrong timestamp size
+ */
+int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
+{
+       int len;
+       const void *data;
+
+       data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
+       if (data == NULL) {
+               fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
+               return -1;
+       }
+       if (len != sizeof(uint32_t)) {
+               debug("FIT timestamp with incorrect size of (%u)\n", len);
+               return -2;
+       }
+
+       *timestamp = uimage_to_cpu(*((uint32_t *)data));
+       return 0;
+}
+
+/**
+ * fit_image_get_node - get node offset for component image of a given unit name
+ * @fit: pointer to the FIT format image header
+ * @image_uname: component image node unit name
+ *
+ * fit_image_get_node() finds a component image (within the '/images'
+ * node) of a provided unit name. If image is found its node offset is
+ * returned to the caller.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_image_get_node(const void *fit, const char *image_uname)
+{
+       int noffset, images_noffset;
+
+       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (images_noffset < 0) {
+               debug("Can't find images parent node '%s' (%s)\n",
+                     FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+               return images_noffset;
+       }
+
+       noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
+       if (noffset < 0) {
+               debug("Can't get node offset for image unit name: '%s' (%s)\n",
+                     image_uname, fdt_strerror(noffset));
+       }
+
+       return noffset;
+}
+
+/**
+ * fit_image_get_os - get os id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @os: pointer to the uint8_t, will hold os numeric id
+ *
+ * fit_image_get_os() finds os property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
+{
+       int len;
+       const void *data;
+
+       /* Get OS name from property data */
+       data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
+       if (data == NULL) {
+               fit_get_debug(fit, noffset, FIT_OS_PROP, len);
+               *os = -1;
+               return -1;
+       }
+
+       /* Translate OS name to id */
+       *os = genimg_get_os_id(data);
+       return 0;
+}
+
+/**
+ * fit_image_get_arch - get arch id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @arch: pointer to the uint8_t, will hold arch numeric id
+ *
+ * fit_image_get_arch() finds arch property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
+{
+       int len;
+       const void *data;
+
+       /* Get architecture name from property data */
+       data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
+       if (data == NULL) {
+               fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
+               *arch = -1;
+               return -1;
+       }
+
+       /* Translate architecture name to id */
+       *arch = genimg_get_arch_id(data);
+       return 0;
+}
+
+/**
+ * fit_image_get_type - get type id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @type: pointer to the uint8_t, will hold type numeric id
+ *
+ * fit_image_get_type() finds type property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
+{
+       int len;
+       const void *data;
+
+       /* Get image type name from property data */
+       data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
+       if (data == NULL) {
+               fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
+               *type = -1;
+               return -1;
+       }
+
+       /* Translate image type name to id */
+       *type = genimg_get_type_id(data);
+       return 0;
+}
+
+/**
+ * fit_image_get_comp - get comp id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @comp: pointer to the uint8_t, will hold comp numeric id
+ *
+ * fit_image_get_comp() finds comp property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
+{
+       int len;
+       const void *data;
+
+       /* Get compression name from property data */
+       data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
+       if (data == NULL) {
+               fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
+               *comp = -1;
+               return -1;
+       }
+
+       /* Translate compression name to id */
+       *comp = genimg_get_comp_id(data);
+       return 0;
+}
+
+static int fit_image_get_address(const void *fit, int noffset, char *name,
+                         ulong *load)
+{
+       int len, cell_len;
+       const fdt32_t *cell;
+       uint64_t load64 = 0;
+
+       cell = fdt_getprop(fit, noffset, name, &len);
+       if (cell == NULL) {
+               fit_get_debug(fit, noffset, name, len);
+               return -1;
+       }
+
+       cell_len = len >> 2;
+       /* Use load64 to avoid compiling warning for 32-bit target */
+       while (cell_len--) {
+               load64 = (load64 << 32) | uimage_to_cpu(*cell);
+               cell++;
+       }
+
+       if (len > sizeof(ulong) && (uint32_t)(load64 >> 32)) {
+               printf("Unsupported %s address size\n", name);
+               return -1;
+       }
+
+       *load = (ulong)load64;
+
+       return 0;
+}
+/**
+ * fit_image_get_load() - get load addr property for given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @load: pointer to the uint32_t, will hold load address
+ *
+ * fit_image_get_load() finds load address property in a given component
+ * image node. If the property is found, its value is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_load(const void *fit, int noffset, ulong *load)
+{
+       return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load);
+}
+
+/**
+ * fit_image_get_entry() - get entry point address property
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @entry: pointer to the uint32_t, will hold entry point address
+ *
+ * This gets the entry point address property for a given component image
+ * node.
+ *
+ * fit_image_get_entry() finds entry point address property in a given
+ * component image node.  If the property is found, its value is returned
+ * to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
+{
+       return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
+}
+
+/**
+ * fit_image_get_data - get data property and its size for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @data: double pointer to void, will hold data property's data address
+ * @size: pointer to size_t, will hold data property's data size
+ *
+ * fit_image_get_data() finds data property in a given component image node.
+ * If the property is found its data start address and size are returned to
+ * the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_data(const void *fit, int noffset,
+               const void **data, size_t *size)
+{
+       int len;
+
+       *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
+       if (*data == NULL) {
+               fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
+               *size = 0;
+               return -1;
+       }
+
+       *size = len;
+       return 0;
+}
+
+/**
+ * Get 'data-offset' property from a given image node.
+ *
+ * @fit: pointer to the FIT image header
+ * @noffset: component image node offset
+ * @data_offset: holds the data-offset property
+ *
+ * returns:
+ *     0, on success
+ *     -ENOENT if the property could not be found
+ */
+int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
+{
+       const fdt32_t *val;
+
+       val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL);
+       if (!val)
+               return -ENOENT;
+
+       *data_offset = fdt32_to_cpu(*val);
+
+       return 0;
+}
+
+/**
+ * Get 'data-position' property from a given image node.
+ *
+ * @fit: pointer to the FIT image header
+ * @noffset: component image node offset
+ * @data_position: holds the data-position property
+ *
+ * returns:
+ *     0, on success
+ *     -ENOENT if the property could not be found
+ */
+int fit_image_get_data_position(const void *fit, int noffset,
+                               int *data_position)
+{
+       const fdt32_t *val;
+
+       val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL);
+       if (!val)
+               return -ENOENT;
+
+       *data_position = fdt32_to_cpu(*val);
+
+       return 0;
+}
+
+/**
+ * Get 'data-size' property from a given image node.
+ *
+ * @fit: pointer to the FIT image header
+ * @noffset: component image node offset
+ * @data_size: holds the data-size property
+ *
+ * returns:
+ *     0, on success
+ *     -ENOENT if the property could not be found
+ */
+int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
+{
+       const fdt32_t *val;
+
+       val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL);
+       if (!val)
+               return -ENOENT;
+
+       *data_size = fdt32_to_cpu(*val);
+
+       return 0;
+}
+
+/**
+ * Get 'data-size-unciphered' property from a given image node.
+ *
+ * @fit: pointer to the FIT image header
+ * @noffset: component image node offset
+ * @data_size: holds the data-size property
+ *
+ * returns:
+ *     0, on success
+ *     -ENOENT if the property could not be found
+ */
+int fit_image_get_data_size_unciphered(const void *fit, int noffset,
+                                      size_t *data_size)
+{
+       const fdt32_t *val;
+
+       val = fdt_getprop(fit, noffset, "data-size-unciphered", NULL);
+       if (!val)
+               return -ENOENT;
+
+       *data_size = (size_t)fdt32_to_cpu(*val);
+
+       return 0;
+}
+
+/**
+ * fit_image_get_data_and_size - get data and its size including
+ *                              both embedded and external data
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @data: double pointer to void, will hold data property's data address
+ * @size: pointer to size_t, will hold data property's data size
+ *
+ * fit_image_get_data_and_size() finds data and its size including
+ * both embedded and external data. If the property is found
+ * its data start address and size are returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     otherwise, on failure
+ */
+int fit_image_get_data_and_size(const void *fit, int noffset,
+                               const void **data, size_t *size)
+{
+       bool external_data = false;
+       int offset;
+       int len;
+       int ret;
+
+       if (!fit_image_get_data_position(fit, noffset, &offset)) {
+               external_data = true;
+       } else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
+               external_data = true;
+               /*
+                * For FIT with external data, figure out where
+                * the external images start. This is the base
+                * for the data-offset properties in each image.
+                */
+               offset += ((fdt_totalsize(fit) + 3) & ~3);
+       }
+
+       if (external_data) {
+               debug("External Data\n");
+               ret = fit_image_get_data_size(fit, noffset, &len);
+               if (!ret) {
+                       *data = fit + offset;
+                       *size = len;
+               }
+       } else {
+               ret = fit_image_get_data(fit, noffset, data, size);
+       }
+
+       return ret;
+}
+
+/**
+ * fit_image_hash_get_algo - get hash algorithm name
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @algo: double pointer to char, will hold pointer to the algorithm name
+ *
+ * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
+ * If the property is found its data start address is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
+{
+       int len;
+
+       *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
+       if (*algo == NULL) {
+               fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * fit_image_hash_get_value - get hash value and length
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @value: double pointer to uint8_t, will hold address of a hash value data
+ * @value_len: pointer to an int, will hold hash data length
+ *
+ * fit_image_hash_get_value() finds hash value property in a given hash node.
+ * If the property is found its data start address and size are returned to
+ * the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
+                               int *value_len)
+{
+       int len;
+
+       *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
+       if (*value == NULL) {
+               fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
+               *value_len = 0;
+               return -1;
+       }
+
+       *value_len = len;
+       return 0;
+}
+
+/**
+ * fit_image_hash_get_ignore - get hash ignore flag
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @ignore: pointer to an int, will hold hash ignore flag
+ *
+ * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
+ * If the property is found and non-zero, the hash algorithm is not verified by
+ * u-boot automatically.
+ *
+ * returns:
+ *     0, on ignore not found
+ *     value, on ignore found
+ */
+static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
+{
+       int len;
+       int *value;
+
+       value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
+       if (value == NULL || len != sizeof(int))
+               *ignore = 0;
+       else
+               *ignore = *value;
+
+       return 0;
+}
+
+/**
+ * fit_image_cipher_get_algo - get cipher algorithm name
+ * @fit: pointer to the FIT format image header
+ * @noffset: cipher node offset
+ * @algo: double pointer to char, will hold pointer to the algorithm name
+ *
+ * fit_image_cipher_get_algo() finds cipher algorithm property in a given
+ * cipher node. If the property is found its data start address is returned
+ * to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo)
+{
+       int len;
+
+       *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
+       if (!*algo) {
+               fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
+               return -1;
+       }
+
+       return 0;
+}
+
+ulong fit_get_end(const void *fit)
+{
+       return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
+}
+
+/**
+ * fit_set_timestamp - set node timestamp property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @timestamp: timestamp value to be set
+ *
+ * fit_set_timestamp() attempts to set timestamp property in the requested
+ * node and returns operation status to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -ENOSPC if no space in device tree, -1 for other error
+ */
+int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
+{
+       uint32_t t;
+       int ret;
+
+       t = cpu_to_uimage(timestamp);
+       ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
+                               sizeof(uint32_t));
+       if (ret) {
+               debug("Can't set '%s' property for '%s' node (%s)\n",
+                     FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
+                     fdt_strerror(ret));
+               return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
+       }
+
+       return 0;
+}
+
+/**
+ * calculate_hash - calculate and return hash for provided input data
+ * @data: pointer to the input data
+ * @data_len: data length
+ * @algo: requested hash algorithm
+ * @value: pointer to the char, will hold hash value data (caller must
+ * allocate enough free space)
+ * value_len: length of the calculated hash
+ *
+ * calculate_hash() computes input data hash according to the requested
+ * algorithm.
+ * Resulting hash value is placed in caller provided 'value' buffer, length
+ * of the calculated hash is returned via value_len pointer argument.
+ *
+ * returns:
+ *     0, on success
+ *    -1, when algo is unsupported
+ */
+int calculate_hash(const void *data, int data_len, const char *name,
+                       uint8_t *value, int *value_len)
+{
+#if !defined(USE_HOSTCC) && defined(CONFIG_DM_HASH)
+       int rc;
+       enum HASH_ALGO hash_algo;
+       struct udevice *dev;
+
+       rc = uclass_get_device(UCLASS_HASH, 0, &dev);
+       if (rc) {
+               debug("failed to get hash device, rc=%d\n", rc);
+               return -1;
+       }
+
+       hash_algo = hash_algo_lookup_by_name(algo);
+       if (hash_algo == HASH_ALGO_INVALID) {
+               debug("Unsupported hash algorithm\n");
+               return -1;
+       };
+
+       rc = hash_digest_wd(dev, hash_algo, data, data_len, value, CHUNKSZ);
+       if (rc) {
+               debug("failed to get hash value, rc=%d\n", rc);
+               return -1;
+       }
+
+       *value_len = hash_algo_digest_size(hash_algo);
+#else
+       struct hash_algo *algo;
+       int ret;
+
+       ret = hash_lookup_algo(name, &algo);
+       if (ret < 0) {
+               debug("Unsupported hash alogrithm\n");
+               return -1;
+       }
+
+       algo->hash_func_ws(data, data_len, value, algo->chunk_size);
+       *value_len = algo->digest_size;
+#endif
+
+       return 0;
+}
+
+static int fit_image_check_hash(const void *fit, int noffset, const void *data,
+                               size_t size, char **err_msgp)
+{
+       uint8_t value[FIT_MAX_HASH_LEN];
+       int value_len;
+       char *algo;
+       uint8_t *fit_value;
+       int fit_value_len;
+       int ignore;
+
+       *err_msgp = NULL;
+
+       if (fit_image_hash_get_algo(fit, noffset, &algo)) {
+               *err_msgp = "Can't get hash algo property";
+               return -1;
+       }
+       printf("%s", algo);
+
+       if (!tools_build()) {
+               fit_image_hash_get_ignore(fit, noffset, &ignore);
+               if (ignore) {
+                       printf("-skipped ");
+                       return 0;
+               }
+       }
+
+       if (fit_image_hash_get_value(fit, noffset, &fit_value,
+                                    &fit_value_len)) {
+               *err_msgp = "Can't get hash value property";
+               return -1;
+       }
+
+       if (calculate_hash(data, size, algo, value, &value_len)) {
+               *err_msgp = "Unsupported hash algorithm";
+               return -1;
+       }
+
+       if (value_len != fit_value_len) {
+               *err_msgp = "Bad hash value len";
+               return -1;
+       } else if (memcmp(value, fit_value, value_len) != 0) {
+               *err_msgp = "Bad hash value";
+               return -1;
+       }
+
+       return 0;
+}
+
+int fit_image_verify_with_data(const void *fit, int image_noffset,
+                              const void *data, size_t size)
+{
+       int             noffset = 0;
+       char            *err_msg = "";
+       int verify_all = 1;
+       int ret;
+
+       /* Verify all required signatures */
+       if (FIT_IMAGE_ENABLE_VERIFY &&
+           fit_image_verify_required_sigs(fit, image_noffset, data, size,
+                                          gd_fdt_blob(), &verify_all)) {
+               err_msg = "Unable to verify required signature";
+               goto error;
+       }
+
+       /* Process all hash subnodes of the component image node */
+       fdt_for_each_subnode(noffset, fit, image_noffset) {
+               const char *name = fit_get_name(fit, noffset, NULL);
+
+               /*
+                * Check subnode name, must be equal to "hash".
+                * Multiple hash nodes require unique unit node
+                * names, e.g. hash-1, hash-2, etc.
+                */
+               if (!strncmp(name, FIT_HASH_NODENAME,
+                            strlen(FIT_HASH_NODENAME))) {
+                       if (fit_image_check_hash(fit, noffset, data, size,
+                                                &err_msg))
+                               goto error;
+                       puts("+ ");
+               } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
+                               !strncmp(name, FIT_SIG_NODENAME,
+                                       strlen(FIT_SIG_NODENAME))) {
+                       ret = fit_image_check_sig(fit, noffset, data,
+                                                       size, -1, &err_msg);
+
+                       /*
+                        * Show an indication on failure, but do not return
+                        * an error. Only keys marked 'required' can cause
+                        * an image validation failure. See the call to
+                        * fit_image_verify_required_sigs() above.
+                        */
+                       if (ret)
+                               puts("- ");
+                       else
+                               puts("+ ");
+               }
+       }
+
+       if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
+               err_msg = "Corrupted or truncated tree";
+               goto error;
+       }
+
+       return 1;
+
+error:
+       printf(" error!\n%s for '%s' hash node in '%s' image node\n",
+              err_msg, fit_get_name(fit, noffset, NULL),
+              fit_get_name(fit, image_noffset, NULL));
+       return 0;
+}
+
+/**
+ * fit_image_verify - verify data integrity
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: component image node offset
+ *
+ * fit_image_verify() goes over component image hash nodes,
+ * re-calculates each data hash and compares with the value stored in hash
+ * node.
+ *
+ * returns:
+ *     1, if all hashes are valid
+ *     0, otherwise (or on error)
+ */
+int fit_image_verify(const void *fit, int image_noffset)
+{
+       const char *name = fit_get_name(fit, image_noffset, NULL);
+       const void      *data;
+       size_t          size;
+       char            *err_msg = "";
+
+       if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
+               /*
+                * We don't support this since libfdt considers names with the
+                * name root but different @ suffix to be equal
+                */
+               err_msg = "Node name contains @";
+               goto err;
+       }
+       /* Get image data and data length */
+       if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
+               err_msg = "Can't get image data/size";
+               goto err;
+       }
+
+       return fit_image_verify_with_data(fit, image_noffset, data, size);
+
+err:
+       printf("error!\n%s in '%s' image node\n", err_msg,
+              fit_get_name(fit, image_noffset, NULL));
+       return 0;
+}
+
+/**
+ * fit_all_image_verify - verify data integrity for all images
+ * @fit: pointer to the FIT format image header
+ *
+ * fit_all_image_verify() goes over all images in the FIT and
+ * for every images checks if all it's hashes are valid.
+ *
+ * returns:
+ *     1, if all hashes of all images are valid
+ *     0, otherwise (or on error)
+ */
+int fit_all_image_verify(const void *fit)
+{
+       int images_noffset;
+       int noffset;
+       int ndepth;
+       int count;
+
+       /* Find images parent node offset */
+       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (images_noffset < 0) {
+               printf("Can't find images parent node '%s' (%s)\n",
+                      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+               return 0;
+       }
+
+       /* Process all image subnodes, check hashes for each */
+       printf("## Checking hash(es) for FIT Image at %08lx ...\n",
+              (ulong)fit);
+       for (ndepth = 0, count = 0,
+            noffset = fdt_next_node(fit, images_noffset, &ndepth);
+                       (noffset >= 0) && (ndepth > 0);
+                       noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       /*
+                        * Direct child node of the images parent node,
+                        * i.e. component image node.
+                        */
+                       printf("   Hash(es) for Image %u (%s): ", count,
+                              fit_get_name(fit, noffset, NULL));
+                       count++;
+
+                       if (!fit_image_verify(fit, noffset))
+                               return 0;
+                       printf("\n");
+               }
+       }
+       return 1;
+}
+
+static int fit_image_uncipher(const void *fit, int image_noffset,
+                             void **data, size_t *size)
+{
+       int cipher_noffset, ret;
+       void *dst;
+       size_t size_dst;
+
+       cipher_noffset = fdt_subnode_offset(fit, image_noffset,
+                                           FIT_CIPHER_NODENAME);
+       if (cipher_noffset < 0)
+               return 0;
+
+       ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
+                                    *data, *size, &dst, &size_dst);
+       if (ret)
+               goto out;
+
+       *data = dst;
+       *size = size_dst;
+
+ out:
+       return ret;
+}
+
+/**
+ * fit_image_check_os - check whether image node is of a given os type
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @os: requested image os
+ *
+ * fit_image_check_os() reads image os property and compares its numeric
+ * id with the requested os. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given os type
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_os(const void *fit, int noffset, uint8_t os)
+{
+       uint8_t image_os;
+
+       if (fit_image_get_os(fit, noffset, &image_os))
+               return 0;
+       return (os == image_os);
+}
+
+/**
+ * fit_image_check_arch - check whether image node is of a given arch
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @arch: requested imagearch
+ *
+ * fit_image_check_arch() reads image arch property and compares its numeric
+ * id with the requested arch. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given arch
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
+{
+       uint8_t image_arch;
+       int aarch32_support = 0;
+
+       /* Let's assume that sandbox can load any architecture */
+       if (IS_ENABLED(CONFIG_SANDBOX))
+               return true;
+
+       if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
+               aarch32_support = 1;
+
+       if (fit_image_get_arch(fit, noffset, &image_arch))
+               return 0;
+       return (arch == image_arch) ||
+               (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
+               (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
+                aarch32_support);
+}
+
+/**
+ * fit_image_check_type - check whether image node is of a given type
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @type: requested image type
+ *
+ * fit_image_check_type() reads image type property and compares its numeric
+ * id with the requested type. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given type
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_type(const void *fit, int noffset, uint8_t type)
+{
+       uint8_t image_type;
+
+       if (fit_image_get_type(fit, noffset, &image_type))
+               return 0;
+       return (type == image_type);
+}
+
+/**
+ * fit_image_check_comp - check whether image node uses given compression
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @comp: requested image compression type
+ *
+ * fit_image_check_comp() reads image compression property and compares its
+ * numeric id with the requested compression type. Comparison result is
+ * returned to the caller.
+ *
+ * returns:
+ *     1 if image uses requested compression
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
+{
+       uint8_t image_comp;
+
+       if (fit_image_get_comp(fit, noffset, &image_comp))
+               return 0;
+       return (comp == image_comp);
+}
+
+/**
+ * fdt_check_no_at() - Check for nodes whose names contain '@'
+ *
+ * This checks the parent node and all subnodes recursively
+ *
+ * @fit: FIT to check
+ * @parent: Parent node to check
+ * @return 0 if OK, -EADDRNOTAVAIL is a node has a name containing '@'
+ */
+static int fdt_check_no_at(const void *fit, int parent)
+{
+       const char *name;
+       int node;
+       int ret;
+
+       name = fdt_get_name(fit, parent, NULL);
+       if (!name || strchr(name, '@'))
+               return -EADDRNOTAVAIL;
+
+       fdt_for_each_subnode(node, fit, parent) {
+               ret = fdt_check_no_at(fit, node);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int fit_check_format(const void *fit, ulong size)
+{
+       int ret;
+
+       /* A FIT image must be a valid FDT */
+       ret = fdt_check_header(fit);
+       if (ret) {
+               log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
+                         ret);
+               return -ENOEXEC;
+       }
+
+       if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
+               /*
+                * If we are not given the size, make do wtih calculating it.
+                * This is not as secure, so we should consider a flag to
+                * control this.
+                */
+               if (size == IMAGE_SIZE_INVAL)
+                       size = fdt_totalsize(fit);
+               ret = fdt_check_full(fit, size);
+               if (ret)
+                       ret = -EINVAL;
+
+               /*
+                * U-Boot stopped using unit addressed in 2017. Since libfdt
+                * can match nodes ignoring any unit address, signature
+                * verification can see the wrong node if one is inserted with
+                * the same name as a valid node but with a unit address
+                * attached. Protect against this by disallowing unit addresses.
+                */
+               if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
+                       ret = fdt_check_no_at(fit, 0);
+
+                       if (ret) {
+                               log_debug("FIT check error %d\n", ret);
+                               return ret;
+                       }
+               }
+               if (ret) {
+                       log_debug("FIT check error %d\n", ret);
+                       return ret;
+               }
+       }
+
+       /* mandatory / node 'description' property */
+       if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
+               log_debug("Wrong FIT format: no description\n");
+               return -ENOMSG;
+       }
+
+       if (IMAGE_ENABLE_TIMESTAMP) {
+               /* mandatory / node 'timestamp' property */
+               if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
+                       log_debug("Wrong FIT format: no timestamp\n");
+                       return -EBADMSG;
+               }
+       }
+
+       /* mandatory subimages parent '/images' node */
+       if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
+               log_debug("Wrong FIT format: no images parent node\n");
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
+/**
+ * fit_conf_find_compat
+ * @fit: pointer to the FIT format image header
+ * @fdt: pointer to the device tree to compare against
+ *
+ * fit_conf_find_compat() attempts to find the configuration whose fdt is the
+ * most compatible with the passed in device tree.
+ *
+ * Example:
+ *
+ * / o image-tree
+ *   |-o images
+ *   | |-o fdt-1
+ *   | |-o fdt-2
+ *   |
+ *   |-o configurations
+ *     |-o config-1
+ *     | |-fdt = fdt-1
+ *     |
+ *     |-o config-2
+ *       |-fdt = fdt-2
+ *
+ * / o U-Boot fdt
+ *   |-compatible = "foo,bar", "bim,bam"
+ *
+ * / o kernel fdt1
+ *   |-compatible = "foo,bar",
+ *
+ * / o kernel fdt2
+ *   |-compatible = "bim,bam", "baz,biz"
+ *
+ * Configuration 1 would be picked because the first string in U-Boot's
+ * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
+ * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
+ *
+ * As an optimization, the compatible property from the FDT's root node can be
+ * copied into the configuration node in the FIT image. This is required to
+ * match configurations with compressed FDTs.
+ *
+ * returns:
+ *     offset to the configuration to use if one was found
+ *     -1 otherwise
+ */
+int fit_conf_find_compat(const void *fit, const void *fdt)
+{
+       int ndepth = 0;
+       int noffset, confs_noffset, images_noffset;
+       const void *fdt_compat;
+       int fdt_compat_len;
+       int best_match_offset = 0;
+       int best_match_pos = 0;
+
+       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
+       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (confs_noffset < 0 || images_noffset < 0) {
+               debug("Can't find configurations or images nodes.\n");
+               return -1;
+       }
+
+       fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
+       if (!fdt_compat) {
+               debug("Fdt for comparison has no \"compatible\" property.\n");
+               return -1;
+       }
+
+       /*
+        * Loop over the configurations in the FIT image.
+        */
+       for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
+                       (noffset >= 0) && (ndepth > 0);
+                       noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               const void *fdt;
+               const char *kfdt_name;
+               int kfdt_noffset, compat_noffset;
+               const char *cur_fdt_compat;
+               int len;
+               size_t sz;
+               int i;
+
+               if (ndepth > 1)
+                       continue;
+
+               /* If there's a compat property in the config node, use that. */
+               if (fdt_getprop(fit, noffset, "compatible", NULL)) {
+                       fdt = fit;                /* search in FIT image */
+                       compat_noffset = noffset; /* search under config node */
+               } else {        /* Otherwise extract it from the kernel FDT. */
+                       kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
+                       if (!kfdt_name) {
+                               debug("No fdt property found.\n");
+                               continue;
+                       }
+                       kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
+                                                         kfdt_name);
+                       if (kfdt_noffset < 0) {
+                               debug("No image node named \"%s\" found.\n",
+                                     kfdt_name);
+                               continue;
+                       }
+
+                       if (!fit_image_check_comp(fit, kfdt_noffset,
+                                                 IH_COMP_NONE)) {
+                               debug("Can't extract compat from \"%s\" "
+                                     "(compressed)\n", kfdt_name);
+                               continue;
+                       }
+
+                       /* search in this config's kernel FDT */
+                       if (fit_image_get_data_and_size(fit, kfdt_noffset,
+                                                       &fdt, &sz)) {
+                               debug("Failed to get fdt \"%s\".\n", kfdt_name);
+                               continue;
+                       }
+
+                       compat_noffset = 0;  /* search kFDT under root node */
+               }
+
+               len = fdt_compat_len;
+               cur_fdt_compat = fdt_compat;
+               /*
+                * Look for a match for each U-Boot compatibility string in
+                * turn in the compat string property.
+                */
+               for (i = 0; len > 0 &&
+                    (!best_match_offset || best_match_pos > i); i++) {
+                       int cur_len = strlen(cur_fdt_compat) + 1;
+
+                       if (!fdt_node_check_compatible(fdt, compat_noffset,
+                                                      cur_fdt_compat)) {
+                               best_match_offset = noffset;
+                               best_match_pos = i;
+                               break;
+                       }
+                       len -= cur_len;
+                       cur_fdt_compat += cur_len;
+               }
+       }
+       if (!best_match_offset) {
+               debug("No match found.\n");
+               return -1;
+       }
+
+       return best_match_offset;
+}
+
+int fit_conf_get_node(const void *fit, const char *conf_uname)
+{
+       int noffset, confs_noffset;
+       int len;
+       const char *s;
+       char *conf_uname_copy = NULL;
+
+       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
+       if (confs_noffset < 0) {
+               debug("Can't find configurations parent node '%s' (%s)\n",
+                     FIT_CONFS_PATH, fdt_strerror(confs_noffset));
+               return confs_noffset;
+       }
+
+       if (conf_uname == NULL) {
+               /* get configuration unit name from the default property */
+               debug("No configuration specified, trying default...\n");
+               if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
+                       noffset = fit_find_config_node(fit);
+                       if (noffset < 0)
+                               return noffset;
+                       conf_uname = fdt_get_name(fit, noffset, NULL);
+               } else {
+                       conf_uname = (char *)fdt_getprop(fit, confs_noffset,
+                                                        FIT_DEFAULT_PROP, &len);
+                       if (conf_uname == NULL) {
+                               fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
+                                             len);
+                               return len;
+                       }
+               }
+               debug("Found default configuration: '%s'\n", conf_uname);
+       }
+
+       s = strchr(conf_uname, '#');
+       if (s) {
+               len = s - conf_uname;
+               conf_uname_copy = malloc(len + 1);
+               if (!conf_uname_copy) {
+                       debug("Can't allocate uname copy: '%s'\n",
+                                       conf_uname);
+                       return -ENOMEM;
+               }
+               memcpy(conf_uname_copy, conf_uname, len);
+               conf_uname_copy[len] = '\0';
+               conf_uname = conf_uname_copy;
+       }
+
+       noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
+       if (noffset < 0) {
+               debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
+                     conf_uname, fdt_strerror(noffset));
+       }
+
+       if (conf_uname_copy)
+               free(conf_uname_copy);
+
+       return noffset;
+}
+
+int fit_conf_get_prop_node_count(const void *fit, int noffset,
+               const char *prop_name)
+{
+       return fdt_stringlist_count(fit, noffset, prop_name);
+}
+
+int fit_conf_get_prop_node_index(const void *fit, int noffset,
+               const char *prop_name, int index)
+{
+       const char *uname;
+       int len;
+
+       /* get kernel image unit name from configuration kernel property */
+       uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
+       if (uname == NULL)
+               return len;
+
+       return fit_image_get_node(fit, uname);
+}
+
+int fit_conf_get_prop_node(const void *fit, int noffset,
+               const char *prop_name)
+{
+       return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
+}
+
+static int fit_image_select(const void *fit, int rd_noffset, int verify)
+{
+       fit_image_print(fit, rd_noffset, "   ");
+
+       if (verify) {
+               puts("   Verifying Hash Integrity ... ");
+               if (!fit_image_verify(fit, rd_noffset)) {
+                       puts("Bad Data Hash\n");
+                       return -EACCES;
+               }
+               puts("OK\n");
+       }
+
+       return 0;
+}
+
+int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
+                       ulong addr)
+{
+       int cfg_noffset;
+       void *fit_hdr;
+       int noffset;
+
+       debug("*  %s: using config '%s' from image at 0x%08lx\n",
+             prop_name, images->fit_uname_cfg, addr);
+
+       /* Check whether configuration has this property defined */
+       fit_hdr = map_sysmem(addr, 0);
+       cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
+       if (cfg_noffset < 0) {
+               debug("*  %s: no such config\n", prop_name);
+               return -EINVAL;
+       }
+
+       noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
+       if (noffset < 0) {
+               debug("*  %s: no '%s' in config\n", prop_name, prop_name);
+               return -ENOENT;
+       }
+
+       return noffset;
+}
+
+/**
+ * fit_get_image_type_property() - get property name for IH_TYPE_...
+ *
+ * @return the properly name where we expect to find the image in the
+ * config node
+ */
+static const char *fit_get_image_type_property(int type)
+{
+       /*
+        * This is sort-of available in the uimage_type[] table in image.c
+        * but we don't have access to the short name, and "fdt" is different
+        * anyway. So let's just keep it here.
+        */
+       switch (type) {
+       case IH_TYPE_FLATDT:
+               return FIT_FDT_PROP;
+       case IH_TYPE_KERNEL:
+               return FIT_KERNEL_PROP;
+       case IH_TYPE_FIRMWARE:
+               return FIT_FIRMWARE_PROP;
+       case IH_TYPE_RAMDISK:
+               return FIT_RAMDISK_PROP;
+       case IH_TYPE_X86_SETUP:
+               return FIT_SETUP_PROP;
+       case IH_TYPE_LOADABLE:
+               return FIT_LOADABLE_PROP;
+       case IH_TYPE_FPGA:
+               return FIT_FPGA_PROP;
+       case IH_TYPE_STANDALONE:
+               return FIT_STANDALONE_PROP;
+       }
+
+       return "unknown";
+}
+
+int fit_image_load(bootm_headers_t *images, ulong addr,
+                  const char **fit_unamep, const char **fit_uname_configp,
+                  int arch, int image_type, int bootstage_id,
+                  enum fit_load_op load_op, ulong *datap, ulong *lenp)
+{
+       int cfg_noffset, noffset;
+       const char *fit_uname;
+       const char *fit_uname_config;
+       const char *fit_base_uname_config;
+       const void *fit;
+       void *buf;
+       void *loadbuf;
+       size_t size;
+       int type_ok, os_ok;
+       ulong load, load_end, data, len;
+       uint8_t os, comp;
+       const char *prop_name;
+       int ret;
+
+       fit = map_sysmem(addr, 0);
+       fit_uname = fit_unamep ? *fit_unamep : NULL;
+       fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
+       fit_base_uname_config = NULL;
+       prop_name = fit_get_image_type_property(image_type);
+       printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
+       ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
+       if (ret) {
+               printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
+               if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
+                       printf("Signature checking prevents use of unit addresses (@) in nodes\n");
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
+               return ret;
+       }
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
+       if (fit_uname) {
+               /* get FIT component image node offset */
+               bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
+               noffset = fit_image_get_node(fit, fit_uname);
+       } else {
+               /*
+                * no image node unit name, try to get config
+                * node first. If config unit node name is NULL
+                * fit_conf_get_node() will try to find default config node
+                */
+               bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
+               if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
+                       cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
+               } else {
+                       cfg_noffset = fit_conf_get_node(fit,
+                                                       fit_uname_config);
+               }
+               if (cfg_noffset < 0) {
+                       puts("Could not find configuration node\n");
+                       bootstage_error(bootstage_id +
+                                       BOOTSTAGE_SUB_NO_UNIT_NAME);
+                       return -ENOENT;
+               }
+
+               fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
+               printf("   Using '%s' configuration\n", fit_base_uname_config);
+               /* Remember this config */
+               if (image_type == IH_TYPE_KERNEL)
+                       images->fit_uname_cfg = fit_base_uname_config;
+
+               if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
+                       puts("   Verifying Hash Integrity ... ");
+                       if (fit_config_verify(fit, cfg_noffset)) {
+                               puts("Bad Data Hash\n");
+                               bootstage_error(bootstage_id +
+                                       BOOTSTAGE_SUB_HASH);
+                               return -EACCES;
+                       }
+                       puts("OK\n");
+               }
+
+               bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
+
+               noffset = fit_conf_get_prop_node(fit, cfg_noffset,
+                                                prop_name);
+               fit_uname = fit_get_name(fit, noffset, NULL);
+       }
+       if (noffset < 0) {
+               printf("Could not find subimage node type '%s'\n", prop_name);
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
+               return -ENOENT;
+       }
+
+       printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);
+
+       ret = fit_image_select(fit, noffset, images->verify);
+       if (ret) {
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
+               return ret;
+       }
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
+       if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
+               if (!fit_image_check_target_arch(fit, noffset)) {
+                       puts("Unsupported Architecture\n");
+                       bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
+                       return -ENOEXEC;
+               }
+       }
+
+#ifndef USE_HOSTCC
+       {
+       uint8_t os_arch;
+
+       fit_image_get_arch(fit, noffset, &os_arch);
+       images->os.arch = os_arch;
+       }
+#endif
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
+       type_ok = fit_image_check_type(fit, noffset, image_type) ||
+                 fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
+                 fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
+                 (image_type == IH_TYPE_KERNEL &&
+                  fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
+
+       os_ok = image_type == IH_TYPE_FLATDT ||
+               image_type == IH_TYPE_FPGA ||
+               fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
+               fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
+               fit_image_check_os(fit, noffset, IH_OS_TEE) ||
+               fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
+               fit_image_check_os(fit, noffset, IH_OS_EFI) ||
+               fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
+
+       /*
+        * If either of the checks fail, we should report an error, but
+        * if the image type is coming from the "loadables" field, we
+        * don't care what it is
+        */
+       if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
+               fit_image_get_os(fit, noffset, &os);
+               printf("No %s %s %s Image\n",
+                      genimg_get_os_name(os),
+                      genimg_get_arch_name(arch),
+                      genimg_get_type_name(image_type));
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
+               return -EIO;
+       }
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
+
+       /* get image data address and length */
+       if (fit_image_get_data_and_size(fit, noffset,
+                                       (const void **)&buf, &size)) {
+               printf("Could not find %s subimage data!\n", prop_name);
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
+               return -ENOENT;
+       }
+
+       /* Decrypt data before uncompress/move */
+       if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
+               puts("   Decrypting Data ... ");
+               if (fit_image_uncipher(fit, noffset, &buf, &size)) {
+                       puts("Error\n");
+                       return -EACCES;
+               }
+               puts("OK\n");
+       }
+
+       /* perform any post-processing on the image data */
+       if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
+               board_fit_image_post_process(fit, noffset, &buf, &size);
+
+       len = (ulong)size;
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
+
+       data = map_to_sysmem(buf);
+       load = data;
+       if (load_op == FIT_LOAD_IGNORED) {
+               /* Don't load */
+       } else if (fit_image_get_load(fit, noffset, &load)) {
+               if (load_op == FIT_LOAD_REQUIRED) {
+                       printf("Can't get %s subimage load address!\n",
+                              prop_name);
+                       bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
+                       return -EBADF;
+               }
+       } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
+               ulong image_start, image_end;
+
+               /*
+                * move image data to the load address,
+                * make sure we don't overwrite initial image
+                */
+               image_start = addr;
+               image_end = addr + fit_get_size(fit);
+
+               load_end = load + len;
+               if (image_type != IH_TYPE_KERNEL &&
+                   load < image_end && load_end > image_start) {
+                       printf("Error: %s overwritten\n", prop_name);
+                       return -EXDEV;
+               }
+
+               printf("   Loading %s from 0x%08lx to 0x%08lx\n",
+                      prop_name, data, load);
+       } else {
+               load = data;    /* No load address specified */
+       }
+
+       comp = IH_COMP_NONE;
+       loadbuf = buf;
+       /* Kernel images get decompressed later in bootm_load_os(). */
+       if (!fit_image_get_comp(fit, noffset, &comp) &&
+           comp != IH_COMP_NONE &&
+           !(image_type == IH_TYPE_KERNEL ||
+             image_type == IH_TYPE_KERNEL_NOLOAD ||
+             image_type == IH_TYPE_RAMDISK)) {
+               ulong max_decomp_len = len * 20;
+               if (load == data) {
+                       loadbuf = malloc(max_decomp_len);
+                       load = map_to_sysmem(loadbuf);
+               } else {
+                       loadbuf = map_sysmem(load, max_decomp_len);
+               }
+               if (image_decomp(comp, load, data, image_type,
+                               loadbuf, buf, len, max_decomp_len, &load_end)) {
+                       printf("Error decompressing %s\n", prop_name);
+
+                       return -ENOEXEC;
+               }
+               len = load_end - load;
+       } else if (load != data) {
+               loadbuf = map_sysmem(load, len);
+               memcpy(loadbuf, buf, len);
+       }
+
+       if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
+               puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
+                    " please fix your .its file!\n");
+
+       /* verify that image data is a proper FDT blob */
+       if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
+               puts("Subimage data is not a FDT");
+               return -ENOEXEC;
+       }
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
+
+       *datap = load;
+       *lenp = len;
+       if (fit_unamep)
+               *fit_unamep = (char *)fit_uname;
+       if (fit_uname_configp)
+               *fit_uname_configp = (char *)(fit_uname_config ? :
+                                             fit_base_uname_config);
+
+       return noffset;
+}
+
+int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
+                       ulong *setup_start, ulong *setup_len)
+{
+       int noffset;
+       ulong addr;
+       ulong len;
+       int ret;
+
+       addr = map_to_sysmem(images->fit_hdr_os);
+       noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
+       if (noffset < 0)
+               return noffset;
+
+       ret = fit_image_load(images, addr, NULL, NULL, arch,
+                            IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
+                            FIT_LOAD_REQUIRED, setup_start, &len);
+
+       return ret;
+}
+
+#ifndef USE_HOSTCC
+int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
+                  const char **fit_unamep, const char **fit_uname_configp,
+                  int arch, ulong *datap, ulong *lenp)
+{
+       int fdt_noffset, cfg_noffset, count;
+       const void *fit;
+       const char *fit_uname = NULL;
+       const char *fit_uname_config = NULL;
+       char *fit_uname_config_copy = NULL;
+       char *next_config = NULL;
+       ulong load, len;
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+       ulong image_start, image_end;
+       ulong ovload, ovlen, ovcopylen;
+       const char *uconfig;
+       const char *uname;
+       void *base, *ov, *ovcopy = NULL;
+       int i, err, noffset, ov_noffset;
+#endif
+
+       fit_uname = fit_unamep ? *fit_unamep : NULL;
+
+       if (fit_uname_configp && *fit_uname_configp) {
+               fit_uname_config_copy = strdup(*fit_uname_configp);
+               if (!fit_uname_config_copy)
+                       return -ENOMEM;
+
+               next_config = strchr(fit_uname_config_copy, '#');
+               if (next_config)
+                       *next_config++ = '\0';
+               if (next_config - 1 > fit_uname_config_copy)
+                       fit_uname_config = fit_uname_config_copy;
+       }
+
+       fdt_noffset = fit_image_load(images,
+               addr, &fit_uname, &fit_uname_config,
+               arch, IH_TYPE_FLATDT,
+               BOOTSTAGE_ID_FIT_FDT_START,
+               FIT_LOAD_OPTIONAL, &load, &len);
+
+       if (fdt_noffset < 0)
+               goto out;
+
+       debug("fit_uname=%s, fit_uname_config=%s\n",
+                       fit_uname ? fit_uname : "<NULL>",
+                       fit_uname_config ? fit_uname_config : "<NULL>");
+
+       fit = map_sysmem(addr, 0);
+
+       cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
+
+       /* single blob, or error just return as well */
+       count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
+       if (count <= 1 && !next_config)
+               goto out;
+
+       /* we need to apply overlays */
+
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+       image_start = addr;
+       image_end = addr + fit_get_size(fit);
+       /* verify that relocation took place by load address not being in fit */
+       if (load >= image_start && load < image_end) {
+               /* check is simplified; fit load checks for overlaps */
+               printf("Overlayed FDT requires relocation\n");
+               fdt_noffset = -EBADF;
+               goto out;
+       }
+
+       base = map_sysmem(load, len);
+
+       /* apply extra configs in FIT first, followed by args */
+       for (i = 1; ; i++) {
+               if (i < count) {
+                       noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
+                                                              FIT_FDT_PROP, i);
+                       uname = fit_get_name(fit, noffset, NULL);
+                       uconfig = NULL;
+               } else {
+                       if (!next_config)
+                               break;
+                       uconfig = next_config;
+                       next_config = strchr(next_config, '#');
+                       if (next_config)
+                               *next_config++ = '\0';
+                       uname = NULL;
+
+                       /*
+                        * fit_image_load() would load the first FDT from the
+                        * extra config only when uconfig is specified.
+                        * Check if the extra config contains multiple FDTs and
+                        * if so, load them.
+                        */
+                       cfg_noffset = fit_conf_get_node(fit, uconfig);
+
+                       i = 0;
+                       count = fit_conf_get_prop_node_count(fit, cfg_noffset,
+                                                            FIT_FDT_PROP);
+               }
+
+               debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
+
+               ov_noffset = fit_image_load(images,
+                       addr, &uname, &uconfig,
+                       arch, IH_TYPE_FLATDT,
+                       BOOTSTAGE_ID_FIT_FDT_START,
+                       FIT_LOAD_IGNORED, &ovload, &ovlen);
+               if (ov_noffset < 0) {
+                       printf("load of %s failed\n", uname);
+                       continue;
+               }
+               debug("%s loaded at 0x%08lx len=0x%08lx\n",
+                               uname, ovload, ovlen);
+               ov = map_sysmem(ovload, ovlen);
+
+               ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
+               ovcopy = malloc(ovcopylen);
+               if (!ovcopy) {
+                       printf("failed to duplicate DTO before application\n");
+                       fdt_noffset = -ENOMEM;
+                       goto out;
+               }
+
+               err = fdt_open_into(ov, ovcopy, ovcopylen);
+               if (err < 0) {
+                       printf("failed on fdt_open_into for DTO\n");
+                       fdt_noffset = err;
+                       goto out;
+               }
+
+               base = map_sysmem(load, len + ovlen);
+               err = fdt_open_into(base, base, len + ovlen);
+               if (err < 0) {
+                       printf("failed on fdt_open_into\n");
+                       fdt_noffset = err;
+                       goto out;
+               }
+
+               /* the verbose method prints out messages on error */
+               err = fdt_overlay_apply_verbose(base, ovcopy);
+               if (err < 0) {
+                       fdt_noffset = err;
+                       goto out;
+               }
+               fdt_pack(base);
+               len = fdt_totalsize(base);
+
+               free(ovcopy);
+               ovcopy = NULL;
+       }
+#else
+       printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
+       fdt_noffset = -EBADF;
+#endif
+
+out:
+       if (datap)
+               *datap = load;
+       if (lenp)
+               *lenp = len;
+       if (fit_unamep)
+               *fit_unamep = fit_uname;
+       if (fit_uname_configp)
+               *fit_uname_configp = fit_uname_config;
+
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+       if (ovcopy)
+               free(ovcopy);
+#endif
+       if (fit_uname_config_copy)
+               free(fit_uname_config_copy);
+       return fdt_noffset;
+}
+#endif
diff --git a/boot/image-host.c b/boot/image-host.c
new file mode 100644 (file)
index 0000000..20a9521
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Image code used by host tools (and not boards)
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <time.h>
+
+void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
+{
+       memmove(to, from, len);
+}
+
+void genimg_print_size(uint32_t size)
+{
+       printf("%d Bytes = %.2f KiB = %.2f MiB\n", size, (double)size / 1.024e3,
+              (double)size / 1.048576e6);
+}
+
+void genimg_print_time(time_t timestamp)
+{
+       printf("%s", ctime(&timestamp));
+}
diff --git a/boot/image-sig.c b/boot/image-sig.c
new file mode 100644 (file)
index 0000000..1aa0b58
--- /dev/null
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013, Google Inc.
+ */
+
+#include <common.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR;
+#include <image.h>
+#include <relocate.h>
+#include <u-boot/ecdsa.h>
+#include <u-boot/rsa.h>
+#include <u-boot/hash-checksum.h>
+
+#define IMAGE_MAX_HASHED_NODES         100
+
+struct checksum_algo checksum_algos[] = {
+       {
+               .name = "sha1",
+               .checksum_len = SHA1_SUM_LEN,
+               .der_len = SHA1_DER_LEN,
+               .der_prefix = sha1_der_prefix,
+               .calculate = hash_calculate,
+       },
+       {
+               .name = "sha256",
+               .checksum_len = SHA256_SUM_LEN,
+               .der_len = SHA256_DER_LEN,
+               .der_prefix = sha256_der_prefix,
+               .calculate = hash_calculate,
+       },
+#ifdef CONFIG_SHA384
+       {
+               .name = "sha384",
+               .checksum_len = SHA384_SUM_LEN,
+               .der_len = SHA384_DER_LEN,
+               .der_prefix = sha384_der_prefix,
+               .calculate = hash_calculate,
+       },
+#endif
+#ifdef CONFIG_SHA512
+       {
+               .name = "sha512",
+               .checksum_len = SHA512_SUM_LEN,
+               .der_len = SHA512_DER_LEN,
+               .der_prefix = sha512_der_prefix,
+               .calculate = hash_calculate,
+       },
+#endif
+
+};
+
+struct checksum_algo *image_get_checksum_algo(const char *full_name)
+{
+       int i;
+       const char *name;
+
+       if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
+               static bool done;
+
+               if (!done) {
+                       done = true;
+                       for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
+                               struct checksum_algo *algo = &checksum_algos[i];
+
+                               MANUAL_RELOC(algo->name);
+                               MANUAL_RELOC(algo->calculate);
+                       }
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
+               name = checksum_algos[i].name;
+               /* Make sure names match and next char is a comma */
+               if (!strncmp(name, full_name, strlen(name)) &&
+                   full_name[strlen(name)] == ',')
+                       return &checksum_algos[i];
+       }
+
+       return NULL;
+}
+
+struct crypto_algo *image_get_crypto_algo(const char *full_name)
+{
+       struct crypto_algo *crypto, *end;
+       const char *name;
+
+       if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
+               static bool done;
+
+               if (!done) {
+                       done = true;
+                       crypto = ll_entry_start(struct crypto_algo, cryptos);
+                       end = ll_entry_end(struct crypto_algo, cryptos);
+                       for (; crypto < end; crypto++) {
+                               MANUAL_RELOC(crypto->name);
+                               MANUAL_RELOC(crypto->verify);
+                       }
+               }
+       }
+
+       /* Move name to after the comma */
+       name = strchr(full_name, ',');
+       if (!name)
+               return NULL;
+       name += 1;
+
+       crypto = ll_entry_start(struct crypto_algo, cryptos);
+       end = ll_entry_end(struct crypto_algo, cryptos);
+       for (; crypto < end; crypto++) {
+               if (!strcmp(crypto->name, name))
+                       return crypto;
+       }
+
+       /* Not found */
+       return NULL;
+}
+
+struct padding_algo *image_get_padding_algo(const char *name)
+{
+       struct padding_algo *padding, *end;
+
+       if (!name)
+               return NULL;
+
+       padding = ll_entry_start(struct padding_algo, paddings);
+       end = ll_entry_end(struct padding_algo, paddings);
+       for (; padding < end; padding++) {
+               if (!strcmp(padding->name, name))
+                       return padding;
+       }
+
+       return NULL;
+}
diff --git a/boot/image.c b/boot/image.c
new file mode 100644 (file)
index 0000000..3fa60b5
--- /dev/null
@@ -0,0 +1,738 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <env.h>
+#include <lmb.h>
+#include <log.h>
+#include <malloc.h>
+#include <u-boot/crc.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+#include <status_led.h>
+#endif
+
+#if CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT)
+#include <linux/libfdt.h>
+#include <fdt_support.h>
+#endif
+
+#include <asm/global_data.h>
+#include <u-boot/md5.h>
+#include <u-boot/sha1.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_CMD_BDI
+extern int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc,
+                    char *const argv[]);
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Set this if we have less than 4 MB of malloc() space */
+#if CONFIG_SYS_MALLOC_LEN < (4096 * 1024)
+#define CONSERVE_MEMORY                true
+#else
+#define CONSERVE_MEMORY                false
+#endif
+
+#else /* USE_HOSTCC */
+#include "mkimage.h"
+#include <u-boot/md5.h>
+#include <time.h>
+
+#ifndef __maybe_unused
+# define __maybe_unused                /* unimplemented */
+#endif
+
+#define CONSERVE_MEMORY                false
+
+#endif /* !USE_HOSTCC*/
+
+#include <abuf.h>
+#include <bzlib.h>
+#include <display_options.h>
+#include <gzip.h>
+#include <image.h>
+#include <imximage.h>
+#include <relocate.h>
+#include <linux/lzo.h>
+#include <linux/zstd.h>
+#include <linux/kconfig.h>
+#include <lzma/LzmaTypes.h>
+#include <lzma/LzmaDec.h>
+#include <lzma/LzmaTools.h>
+#include <u-boot/crc.h>
+#include <u-boot/lz4.h>
+
+static const table_entry_t uimage_arch[] = {
+       {       IH_ARCH_INVALID,        "invalid",      "Invalid ARCH", },
+       {       IH_ARCH_ALPHA,          "alpha",        "Alpha",        },
+       {       IH_ARCH_ARM,            "arm",          "ARM",          },
+       {       IH_ARCH_I386,           "x86",          "Intel x86",    },
+       {       IH_ARCH_IA64,           "ia64",         "IA64",         },
+       {       IH_ARCH_M68K,           "m68k",         "M68K",         },
+       {       IH_ARCH_MICROBLAZE,     "microblaze",   "MicroBlaze",   },
+       {       IH_ARCH_MIPS,           "mips",         "MIPS",         },
+       {       IH_ARCH_MIPS64,         "mips64",       "MIPS 64 Bit",  },
+       {       IH_ARCH_NIOS2,          "nios2",        "NIOS II",      },
+       {       IH_ARCH_PPC,            "powerpc",      "PowerPC",      },
+       {       IH_ARCH_PPC,            "ppc",          "PowerPC",      },
+       {       IH_ARCH_S390,           "s390",         "IBM S390",     },
+       {       IH_ARCH_SH,             "sh",           "SuperH",       },
+       {       IH_ARCH_SPARC,          "sparc",        "SPARC",        },
+       {       IH_ARCH_SPARC64,        "sparc64",      "SPARC 64 Bit", },
+       {       IH_ARCH_BLACKFIN,       "blackfin",     "Blackfin",     },
+       {       IH_ARCH_AVR32,          "avr32",        "AVR32",        },
+       {       IH_ARCH_NDS32,          "nds32",        "NDS32",        },
+       {       IH_ARCH_OPENRISC,       "or1k",         "OpenRISC 1000",},
+       {       IH_ARCH_SANDBOX,        "sandbox",      "Sandbox",      },
+       {       IH_ARCH_ARM64,          "arm64",        "AArch64",      },
+       {       IH_ARCH_ARC,            "arc",          "ARC",          },
+       {       IH_ARCH_X86_64,         "x86_64",       "AMD x86_64",   },
+       {       IH_ARCH_XTENSA,         "xtensa",       "Xtensa",       },
+       {       IH_ARCH_RISCV,          "riscv",        "RISC-V",       },
+       {       -1,                     "",             "",             },
+};
+
+static const table_entry_t uimage_os[] = {
+       {       IH_OS_INVALID,  "invalid",      "Invalid OS",           },
+       {       IH_OS_ARM_TRUSTED_FIRMWARE, "arm-trusted-firmware", "ARM Trusted Firmware"  },
+       {       IH_OS_LINUX,    "linux",        "Linux",                },
+#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
+       {       IH_OS_LYNXOS,   "lynxos",       "LynxOS",               },
+#endif
+       {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
+       {       IH_OS_OSE,      "ose",          "Enea OSE",             },
+       {       IH_OS_PLAN9,    "plan9",        "Plan 9",               },
+       {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
+       {       IH_OS_TEE,      "tee",          "Trusted Execution Environment" },
+       {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
+       {       IH_OS_VXWORKS,  "vxworks",      "VxWorks",              },
+#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
+       {       IH_OS_QNX,      "qnx",          "QNX",                  },
+#endif
+#if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
+       {       IH_OS_INTEGRITY,"integrity",    "INTEGRITY",            },
+#endif
+#ifdef USE_HOSTCC
+       {       IH_OS_4_4BSD,   "4_4bsd",       "4_4BSD",               },
+       {       IH_OS_DELL,     "dell",         "Dell",                 },
+       {       IH_OS_ESIX,     "esix",         "Esix",                 },
+       {       IH_OS_FREEBSD,  "freebsd",      "FreeBSD",              },
+       {       IH_OS_IRIX,     "irix",         "Irix",                 },
+       {       IH_OS_NCR,      "ncr",          "NCR",                  },
+       {       IH_OS_OPENBSD,  "openbsd",      "OpenBSD",              },
+       {       IH_OS_PSOS,     "psos",         "pSOS",                 },
+       {       IH_OS_SCO,      "sco",          "SCO",                  },
+       {       IH_OS_SOLARIS,  "solaris",      "Solaris",              },
+       {       IH_OS_SVR4,     "svr4",         "SVR4",                 },
+#endif
+#if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC)
+       {       IH_OS_OPENRTOS, "openrtos",     "OpenRTOS",             },
+#endif
+       {       IH_OS_OPENSBI,  "opensbi",      "RISC-V OpenSBI",       },
+       {       IH_OS_EFI,      "efi",          "EFI Firmware" },
+
+       {       -1,             "",             "",                     },
+};
+
+static const table_entry_t uimage_type[] = {
+       {       IH_TYPE_AISIMAGE,   "aisimage",   "Davinci AIS image",},
+       {       IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",   },
+       {       IH_TYPE_FIRMWARE,   "firmware",   "Firmware",           },
+       {       IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",   },
+       {       IH_TYPE_GPIMAGE,    "gpimage",    "TI Keystone SPL Image",},
+       {       IH_TYPE_KERNEL,     "kernel",     "Kernel Image",       },
+       {       IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
+       {       IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
+       {       IH_TYPE_IMXIMAGE,   "imximage",   "Freescale i.MX Boot Image",},
+       {       IH_TYPE_IMX8IMAGE,  "imx8image",  "NXP i.MX8 Boot Image",},
+       {       IH_TYPE_IMX8MIMAGE, "imx8mimage", "NXP i.MX8M Boot Image",},
+       {       IH_TYPE_INVALID,    "invalid",    "Invalid Image",      },
+       {       IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
+       {       IH_TYPE_OMAPIMAGE,  "omapimage",  "TI OMAP SPL With GP CH",},
+       {       IH_TYPE_PBLIMAGE,   "pblimage",   "Freescale PBL Boot Image",},
+       {       IH_TYPE_RAMDISK,    "ramdisk",    "RAMDisk Image",      },
+       {       IH_TYPE_SCRIPT,     "script",     "Script",             },
+       {       IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SoCFPGA CV/AV preloader",},
+       {       IH_TYPE_SOCFPGAIMAGE_V1, "socfpgaimage_v1", "Altera SoCFPGA A10 preloader",},
+       {       IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
+       {       IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
+       {       IH_TYPE_MXSIMAGE,   "mxsimage",   "Freescale MXS Boot Image",},
+       {       IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",},
+       {       IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
+       {       IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
+       {       IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
+       {       IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
+       {       IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
+       {       IH_TYPE_VYBRIDIMAGE, "vybridimage",  "Vybrid Boot Image", },
+       {       IH_TYPE_ZYNQIMAGE,  "zynqimage",  "Xilinx Zynq Boot Image" },
+       {       IH_TYPE_ZYNQMPIMAGE, "zynqmpimage", "Xilinx ZynqMP Boot Image" },
+       {       IH_TYPE_ZYNQMPBIF,  "zynqmpbif",  "Xilinx ZynqMP Boot Image (bif)" },
+       {       IH_TYPE_FPGA,       "fpga",       "FPGA Image" },
+       {       IH_TYPE_TEE,        "tee",        "Trusted Execution Environment Image",},
+       {       IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },
+       {       IH_TYPE_PMMC,        "pmmc",        "TI Power Management Micro-Controller Firmware",},
+       {       IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" },
+       {       IH_TYPE_MTKIMAGE,   "mtk_image",   "MediaTek BootROM loadable Image" },
+       {       IH_TYPE_COPRO, "copro", "Coprocessor Image"},
+       {       IH_TYPE_SUNXI_EGON, "sunxi_egon",  "Allwinner eGON Boot Image" },
+       {       -1,                 "",           "",                   },
+};
+
+static const table_entry_t uimage_comp[] = {
+       {       IH_COMP_NONE,   "none",         "uncompressed",         },
+       {       IH_COMP_BZIP2,  "bzip2",        "bzip2 compressed",     },
+       {       IH_COMP_GZIP,   "gzip",         "gzip compressed",      },
+       {       IH_COMP_LZMA,   "lzma",         "lzma compressed",      },
+       {       IH_COMP_LZO,    "lzo",          "lzo compressed",       },
+       {       IH_COMP_LZ4,    "lz4",          "lz4 compressed",       },
+       {       IH_COMP_ZSTD,   "zstd",         "zstd compressed",      },
+       {       -1,             "",             "",                     },
+};
+
+struct table_info {
+       const char *desc;
+       int count;
+       const table_entry_t *table;
+};
+
+static const struct comp_magic_map image_comp[] = {
+       {       IH_COMP_BZIP2,  "bzip2",        {0x42, 0x5a},},
+       {       IH_COMP_GZIP,   "gzip",         {0x1f, 0x8b},},
+       {       IH_COMP_LZMA,   "lzma",         {0x5d, 0x00},},
+       {       IH_COMP_LZO,    "lzo",          {0x89, 0x4c},},
+       {       IH_COMP_LZ4,    "lz4",          {0x04, 0x22},},
+       {       IH_COMP_ZSTD,   "zstd",         {0x28, 0xb5},},
+       {       IH_COMP_NONE,   "none",         {},     },
+};
+
+static const struct table_info table_info[IH_COUNT] = {
+       { "architecture", IH_ARCH_COUNT, uimage_arch },
+       { "compression", IH_COMP_COUNT, uimage_comp },
+       { "operating system", IH_OS_COUNT, uimage_os },
+       { "image type", IH_TYPE_COUNT, uimage_type },
+};
+
+/*****************************************************************************/
+/* Legacy format routines */
+/*****************************************************************************/
+int image_check_hcrc(const image_header_t *hdr)
+{
+       ulong hcrc;
+       ulong len = image_get_header_size();
+       image_header_t header;
+
+       /* Copy header so we can blank CRC field for re-calculation */
+       memmove(&header, (char *)hdr, image_get_header_size());
+       image_set_hcrc(&header, 0);
+
+       hcrc = crc32(0, (unsigned char *)&header, len);
+
+       return (hcrc == image_get_hcrc(hdr));
+}
+
+int image_check_dcrc(const image_header_t *hdr)
+{
+       ulong data = image_get_data(hdr);
+       ulong len = image_get_data_size(hdr);
+       ulong dcrc = crc32_wd(0, (unsigned char *)data, len, CHUNKSZ_CRC32);
+
+       return (dcrc == image_get_dcrc(hdr));
+}
+
+/**
+ * image_multi_count - get component (sub-image) count
+ * @hdr: pointer to the header of the multi component image
+ *
+ * image_multi_count() returns number of components in a multi
+ * component image.
+ *
+ * Note: no checking of the image type is done, caller must pass
+ * a valid multi component image.
+ *
+ * returns:
+ *     number of components
+ */
+ulong image_multi_count(const image_header_t *hdr)
+{
+       ulong i, count = 0;
+       uint32_t *size;
+
+       /* get start of the image payload, which in case of multi
+        * component images that points to a table of component sizes */
+       size = (uint32_t *)image_get_data(hdr);
+
+       /* count non empty slots */
+       for (i = 0; size[i]; ++i)
+               count++;
+
+       return count;
+}
+
+/**
+ * image_multi_getimg - get component data address and size
+ * @hdr: pointer to the header of the multi component image
+ * @idx: index of the requested component
+ * @data: pointer to a ulong variable, will hold component data address
+ * @len: pointer to a ulong variable, will hold component size
+ *
+ * image_multi_getimg() returns size and data address for the requested
+ * component in a multi component image.
+ *
+ * Note: no checking of the image type is done, caller must pass
+ * a valid multi component image.
+ *
+ * returns:
+ *     data address and size of the component, if idx is valid
+ *     0 in data and len, if idx is out of range
+ */
+void image_multi_getimg(const image_header_t *hdr, ulong idx,
+                       ulong *data, ulong *len)
+{
+       int i;
+       uint32_t *size;
+       ulong offset, count, img_data;
+
+       /* get number of component */
+       count = image_multi_count(hdr);
+
+       /* get start of the image payload, which in case of multi
+        * component images that points to a table of component sizes */
+       size = (uint32_t *)image_get_data(hdr);
+
+       /* get address of the proper component data start, which means
+        * skipping sizes table (add 1 for last, null entry) */
+       img_data = image_get_data(hdr) + (count + 1) * sizeof(uint32_t);
+
+       if (idx < count) {
+               *len = uimage_to_cpu(size[idx]);
+               offset = 0;
+
+               /* go over all indices preceding requested component idx */
+               for (i = 0; i < idx; i++) {
+                       /* add up i-th component size, rounding up to 4 bytes */
+                       offset += (uimage_to_cpu(size[i]) + 3) & ~3 ;
+               }
+
+               /* calculate idx-th component data address */
+               *data = img_data + offset;
+       } else {
+               *len = 0;
+               *data = 0;
+       }
+}
+
+static void image_print_type(const image_header_t *hdr)
+{
+       const char __maybe_unused *os, *arch, *type, *comp;
+
+       os = genimg_get_os_name(image_get_os(hdr));
+       arch = genimg_get_arch_name(image_get_arch(hdr));
+       type = genimg_get_type_name(image_get_type(hdr));
+       comp = genimg_get_comp_name(image_get_comp(hdr));
+
+       printf("%s %s %s (%s)\n", arch, os, type, comp);
+}
+
+/**
+ * image_print_contents - prints out the contents of the legacy format image
+ * @ptr: pointer to the legacy format image header
+ * @p: pointer to prefix string
+ *
+ * image_print_contents() formats a multi line legacy image contents description.
+ * The routine prints out all header fields followed by the size/offset data
+ * for MULTI/SCRIPT images.
+ *
+ * returns:
+ *     no returned results
+ */
+void image_print_contents(const void *ptr)
+{
+       const image_header_t *hdr = (const image_header_t *)ptr;
+       const char __maybe_unused *p;
+
+       p = IMAGE_INDENT_STRING;
+       printf("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name(hdr));
+       if (IMAGE_ENABLE_TIMESTAMP) {
+               printf("%sCreated:      ", p);
+               genimg_print_time((time_t)image_get_time(hdr));
+       }
+       printf("%sImage Type:   ", p);
+       image_print_type(hdr);
+       printf("%sData Size:    ", p);
+       genimg_print_size(image_get_data_size(hdr));
+       printf("%sLoad Address: %08x\n", p, image_get_load(hdr));
+       printf("%sEntry Point:  %08x\n", p, image_get_ep(hdr));
+
+       if (image_check_type(hdr, IH_TYPE_MULTI) ||
+                       image_check_type(hdr, IH_TYPE_SCRIPT)) {
+               int i;
+               ulong data, len;
+               ulong count = image_multi_count(hdr);
+
+               printf("%sContents:\n", p);
+               for (i = 0; i < count; i++) {
+                       image_multi_getimg(hdr, i, &data, &len);
+
+                       printf("%s   Image %d: ", p, i);
+                       genimg_print_size(len);
+
+                       if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) {
+                               /*
+                                * the user may need to know offsets
+                                * if planning to do something with
+                                * multiple files
+                                */
+                               printf("%s    Offset = 0x%08lx\n", p, data);
+                       }
+               }
+       } else if (image_check_type(hdr, IH_TYPE_FIRMWARE_IVT)) {
+               printf("HAB Blocks:   0x%08x   0x0000   0x%08x\n",
+                       image_get_load(hdr) - image_get_header_size(),
+                       (int)(image_get_size(hdr) + image_get_header_size()
+                       + sizeof(flash_header_v2_t) - 0x2060));
+       }
+}
+
+/**
+ * print_decomp_msg() - Print a suitable decompression/loading message
+ *
+ * @type:      OS type (IH_OS_...)
+ * @comp_type: Compression type being used (IH_COMP_...)
+ * @is_xip:    true if the load address matches the image start
+ */
+static void print_decomp_msg(int comp_type, int type, bool is_xip)
+{
+       const char *name = genimg_get_type_name(type);
+
+       if (comp_type == IH_COMP_NONE)
+               printf("   %s %s\n", is_xip ? "XIP" : "Loading", name);
+       else
+               printf("   Uncompressing %s\n", name);
+}
+
+int image_decomp_type(const unsigned char *buf, ulong len)
+{
+       const struct comp_magic_map *cmagic = image_comp;
+
+       if (len < 2)
+               return -EINVAL;
+
+       for (; cmagic->comp_id > 0; cmagic++) {
+               if (!memcmp(buf, cmagic->magic, 2))
+                       break;
+       }
+
+       return cmagic->comp_id;
+}
+
+int image_decomp(int comp, ulong load, ulong image_start, int type,
+                void *load_buf, void *image_buf, ulong image_len,
+                uint unc_len, ulong *load_end)
+{
+       int ret = -ENOSYS;
+
+       *load_end = load;
+       print_decomp_msg(comp, type, load == image_start);
+
+       /*
+        * Load the image to the right place, decompressing if needed. After
+        * this, image_len will be set to the number of uncompressed bytes
+        * loaded, ret will be non-zero on error.
+        */
+       switch (comp) {
+       case IH_COMP_NONE:
+               ret = 0;
+               if (load == image_start)
+                       break;
+               if (image_len <= unc_len)
+                       memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
+               else
+                       ret = -ENOSPC;
+               break;
+       case IH_COMP_GZIP:
+               if (!tools_build() && CONFIG_IS_ENABLED(GZIP))
+                       ret = gunzip(load_buf, unc_len, image_buf, &image_len);
+               break;
+       case IH_COMP_BZIP2:
+               if (!tools_build() && CONFIG_IS_ENABLED(BZIP2)) {
+                       uint size = unc_len;
+
+                       /*
+                        * If we've got less than 4 MB of malloc() space,
+                        * use slower decompression algorithm which requires
+                        * at most 2300 KB of memory.
+                        */
+                       ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
+                               image_buf, image_len, CONSERVE_MEMORY, 0);
+                       image_len = size;
+               }
+               break;
+       case IH_COMP_LZMA:
+               if (!tools_build() && CONFIG_IS_ENABLED(LZMA)) {
+                       SizeT lzma_len = unc_len;
+
+                       ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
+                                                      image_buf, image_len);
+                       image_len = lzma_len;
+               }
+               break;
+       case IH_COMP_LZO:
+               if (!tools_build() && CONFIG_IS_ENABLED(LZO)) {
+                       size_t size = unc_len;
+
+                       ret = lzop_decompress(image_buf, image_len, load_buf, &size);
+                       image_len = size;
+               }
+               break;
+       case IH_COMP_LZ4:
+               if (!tools_build() && CONFIG_IS_ENABLED(LZ4)) {
+                       size_t size = unc_len;
+
+                       ret = ulz4fn(image_buf, image_len, load_buf, &size);
+                       image_len = size;
+               }
+               break;
+       case IH_COMP_ZSTD:
+               if (!tools_build() && CONFIG_IS_ENABLED(ZSTD)) {
+                       struct abuf in, out;
+
+                       abuf_init_set(&in, image_buf, image_len);
+                       abuf_init_set(&in, load_buf, unc_len);
+                       ret = zstd_decompress(&in, &out);
+                       if (ret >= 0) {
+                               image_len = ret;
+                               ret = 0;
+                       }
+               }
+               break;
+       }
+       if (ret == -ENOSYS) {
+               printf("Unimplemented compression type %d\n", comp);
+               return ret;
+       }
+       if (ret)
+               return ret;
+
+       *load_end = load + image_len;
+
+       return 0;
+}
+
+const table_entry_t *get_table_entry(const table_entry_t *table, int id)
+{
+       for (; table->id >= 0; ++table) {
+               if (table->id == id)
+                       return table;
+       }
+       return NULL;
+}
+
+static const char *unknown_msg(enum ih_category category)
+{
+       static const char unknown_str[] = "Unknown ";
+       static char msg[30];
+
+       strcpy(msg, unknown_str);
+       strncat(msg, table_info[category].desc,
+               sizeof(msg) - sizeof(unknown_str));
+
+       return msg;
+}
+
+/**
+ * genimg_get_cat_name - translate entry id to long name
+ * @category: category to look up (enum ih_category)
+ * @id: entry id to be translated
+ *
+ * This will scan the translation table trying to find the entry that matches
+ * the given id.
+ *
+ * @return long entry name if translation succeeds; error string on failure
+ */
+const char *genimg_get_cat_name(enum ih_category category, uint id)
+{
+       const table_entry_t *entry;
+
+       entry = get_table_entry(table_info[category].table, id);
+       if (!entry)
+               return unknown_msg(category);
+       return manual_reloc(entry->lname);
+}
+
+/**
+ * genimg_get_cat_short_name - translate entry id to short name
+ * @category: category to look up (enum ih_category)
+ * @id: entry id to be translated
+ *
+ * This will scan the translation table trying to find the entry that matches
+ * the given id.
+ *
+ * @return short entry name if translation succeeds; error string on failure
+ */
+const char *genimg_get_cat_short_name(enum ih_category category, uint id)
+{
+       const table_entry_t *entry;
+
+       entry = get_table_entry(table_info[category].table, id);
+       if (!entry)
+               return unknown_msg(category);
+       return manual_reloc(entry->sname);
+}
+
+int genimg_get_cat_count(enum ih_category category)
+{
+       return table_info[category].count;
+}
+
+const char *genimg_get_cat_desc(enum ih_category category)
+{
+       return table_info[category].desc;
+}
+
+/**
+ * genimg_cat_has_id - check whether category has entry id
+ * @category: category to look up (enum ih_category)
+ * @id: entry id to be checked
+ *
+ * This will scan the translation table trying to find the entry that matches
+ * the given id.
+ *
+ * @return true if category has entry id; false if not
+ */
+bool genimg_cat_has_id(enum ih_category category, uint id)
+{
+       if (get_table_entry(table_info[category].table, id))
+               return true;
+
+       return false;
+}
+
+/**
+ * get_table_entry_name - translate entry id to long name
+ * @table: pointer to a translation table for entries of a specific type
+ * @msg: message to be returned when translation fails
+ * @id: entry id to be translated
+ *
+ * get_table_entry_name() will go over translation table trying to find
+ * entry that matches given id. If matching entry is found, its long
+ * name is returned to the caller.
+ *
+ * returns:
+ *     long entry name if translation succeeds
+ *     msg otherwise
+ */
+char *get_table_entry_name(const table_entry_t *table, char *msg, int id)
+{
+       table = get_table_entry(table, id);
+       if (!table)
+               return msg;
+       return manual_reloc(table->lname);
+}
+
+const char *genimg_get_os_name(uint8_t os)
+{
+       return (get_table_entry_name(uimage_os, "Unknown OS", os));
+}
+
+const char *genimg_get_arch_name(uint8_t arch)
+{
+       return (get_table_entry_name(uimage_arch, "Unknown Architecture",
+                                       arch));
+}
+
+const char *genimg_get_type_name(uint8_t type)
+{
+       return (get_table_entry_name(uimage_type, "Unknown Image", type));
+}
+
+const char *genimg_get_comp_name(uint8_t comp)
+{
+       return (get_table_entry_name(uimage_comp, "Unknown Compression",
+                                       comp));
+}
+
+static const char *genimg_get_short_name(const table_entry_t *table, int val)
+{
+       table = get_table_entry(table, val);
+       if (!table)
+               return "unknown";
+       return manual_reloc(table->sname);
+}
+
+const char *genimg_get_type_short_name(uint8_t type)
+{
+       return genimg_get_short_name(uimage_type, type);
+}
+
+const char *genimg_get_comp_short_name(uint8_t comp)
+{
+       return genimg_get_short_name(uimage_comp, comp);
+}
+
+const char *genimg_get_os_short_name(uint8_t os)
+{
+       return genimg_get_short_name(uimage_os, os);
+}
+
+const char *genimg_get_arch_short_name(uint8_t arch)
+{
+       return genimg_get_short_name(uimage_arch, arch);
+}
+
+/**
+ * get_table_entry_id - translate short entry name to id
+ * @table: pointer to a translation table for entries of a specific type
+ * @table_name: to be used in case of error
+ * @name: entry short name to be translated
+ *
+ * get_table_entry_id() will go over translation table trying to find
+ * entry that matches given short name. If matching entry is found,
+ * its id returned to the caller.
+ *
+ * returns:
+ *     entry id if translation succeeds
+ *     -1 otherwise
+ */
+int get_table_entry_id(const table_entry_t *table,
+               const char *table_name, const char *name)
+{
+       const table_entry_t *t;
+
+       for (t = table; t->id >= 0; ++t) {
+               if (t->sname && !strcasecmp(manual_reloc(t->sname), name))
+                       return t->id;
+       }
+       debug("Invalid %s Type: %s\n", table_name, name);
+
+       return -1;
+}
+
+int genimg_get_os_id(const char *name)
+{
+       return (get_table_entry_id(uimage_os, "OS", name));
+}
+
+int genimg_get_arch_id(const char *name)
+{
+       return (get_table_entry_id(uimage_arch, "CPU", name));
+}
+
+int genimg_get_type_id(const char *name)
+{
+       return (get_table_entry_id(uimage_type, "Image", name));
+}
+
+int genimg_get_comp_id(const char *name)
+{
+       return (get_table_entry_id(uimage_comp, "Compression", name));
+}
index d6f77ab7b9cebf580381668f1bedac267762f3da..fdcf4536d0f0abae28984238a5908416bc0e8235 100644 (file)
@@ -1,5 +1,3 @@
-source "common/Kconfig.boot"
-
 menu "Console"
 
 config MENU
diff --git a/common/Kconfig.boot b/common/Kconfig.boot
deleted file mode 100644 (file)
index a8d4be2..0000000
+++ /dev/null
@@ -1,1036 +0,0 @@
-menu "Boot options"
-
-menu "Boot images"
-
-config ANDROID_BOOT_IMAGE
-       bool "Enable support for Android Boot Images"
-       default y if FASTBOOT
-       help
-         This enables support for booting images which use the Android
-         image format header.
-
-config FIT
-       bool "Support Flattened Image Tree"
-       select HASH
-       select MD5
-       select SHA1
-       imply SHA256
-       help
-         This option allows you to boot the new uImage structure,
-         Flattened Image Tree.  FIT is formally a FDT, which can include
-         images of various types (kernel, FDT blob, ramdisk, etc.)
-         in a single blob.  To boot this new uImage structure,
-         pass the address of the blob to the "bootm" command.
-         FIT is very flexible, supporting compression, multiple images,
-         multiple configurations, verification through hashing and also
-         verified boot (secure boot using RSA).
-
-if FIT
-
-config FIT_EXTERNAL_OFFSET
-       hex "FIT external data offset"
-       default 0x0
-       help
-         This specifies a data offset in fit image.
-         The offset is from data payload offset to the beginning of
-         fit image header. When specifies a offset, specific data
-         could be put in the hole between data payload and fit image
-         header, such as CSF data on i.MX platform.
-
-config FIT_FULL_CHECK
-       bool "Do a full check of the FIT before using it"
-       default y
-       help
-         Enable this do a full check of the FIT to make sure it is valid. This
-         helps to protect against carefully crafted FITs which take advantage
-         of bugs or omissions in the code. This includes a bad structure,
-         multiple root nodes and the like.
-
-config FIT_SIGNATURE
-       bool "Enable signature verification of FIT uImages"
-       depends on DM
-       select HASH
-       imply RSA
-       imply RSA_VERIFY
-       select IMAGE_SIGN_INFO
-       select FIT_FULL_CHECK
-       help
-         This option enables signature verification of FIT uImages,
-         using a hash signed and verified using RSA. If
-         CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
-         hashing is available using hardware, then the RSA library will use
-         it. See doc/uImage.FIT/signature.txt for more details.
-
-         WARNING: When relying on signed FIT images with a required signature
-         check the legacy image format is disabled by default, so that
-         unsigned images cannot be loaded. If a board needs the legacy image
-         format support in this case, enable it using
-         CONFIG_LEGACY_IMAGE_FORMAT.
-
-config FIT_SIGNATURE_MAX_SIZE
-       hex "Max size of signed FIT structures"
-       depends on FIT_SIGNATURE
-       default 0x10000000
-       help
-         This option sets a max size in bytes for verified FIT uImages.
-         A sane value of 256MB protects corrupted DTB structures from overlapping
-         device memory. Assure this size does not extend past expected storage
-         space.
-
-config FIT_RSASSA_PSS
-       bool "Support rsassa-pss signature scheme of FIT image contents"
-       depends on FIT_SIGNATURE
-       help
-         Enable this to support the pss padding algorithm as described
-         in the rfc8017 (https://tools.ietf.org/html/rfc8017).
-
-config FIT_CIPHER
-       bool "Enable ciphering data in a FIT uImages"
-       depends on DM
-       select AES
-       help
-         Enable the feature of data ciphering/unciphering in the tool mkimage
-         and in the u-boot support of the FIT image.
-
-config FIT_VERBOSE
-       bool "Show verbose messages when FIT images fail"
-       help
-         Generally a system will have valid FIT images so debug messages
-         are a waste of code space. If you are debugging your images then
-         you can enable this option to get more verbose information about
-         failures.
-
-config FIT_BEST_MATCH
-       bool "Select the best match for the kernel device tree"
-       help
-         When no configuration is explicitly selected, default to the
-         one whose fdt's compatibility field best matches that of
-         U-Boot itself. A match is considered "best" if it matches the
-         most specific compatibility entry of U-Boot's fdt's root node.
-         The order of entries in the configuration's fdt is ignored.
-
-config FIT_IMAGE_POST_PROCESS
-       bool "Enable post-processing of FIT artifacts after loading by U-Boot"
-       depends on TI_SECURE_DEVICE || SOCFPGA_SECURE_VAB_AUTH
-       help
-         Allows doing any sort of manipulation to blobs after they got extracted
-         from FIT images like stripping off headers or modifying the size of the
-         blob, verification, authentication, decryption etc. in a platform or
-         board specific way. In order to use this feature a platform or board-
-         specific implementation of board_fit_image_post_process() must be
-         provided. Also, anything done during this post-processing step would
-         need to be comprehended in how the images were prepared before being
-         injected into the FIT creation (i.e. the blobs would have been pre-
-         processed before being added to the FIT image).
-
-config FIT_PRINT
-        bool "Support FIT printing"
-        default y
-        help
-          Support printing the content of the fitImage in a verbose manner.
-
-if SPL
-
-config SPL_FIT
-       bool "Support Flattened Image Tree within SPL"
-       depends on SPL
-       select SPL_HASH
-       select SPL_OF_LIBFDT
-
-config SPL_FIT_PRINT
-       bool "Support FIT printing within SPL"
-       depends on SPL_FIT
-       help
-         Support printing the content of the fitImage in a verbose manner in SPL.
-
-config SPL_FIT_FULL_CHECK
-       bool "Do a full check of the FIT before using it"
-       help
-         Enable this do a full check of the FIT to make sure it is valid. This
-         helps to protect against carefully crafted FITs which take advantage
-         of bugs or omissions in the code. This includes a bad structure,
-         multiple root nodes and the like.
-
-
-config SPL_FIT_SIGNATURE
-       bool "Enable signature verification of FIT firmware within SPL"
-       depends on SPL_DM
-       depends on SPL_LOAD_FIT || SPL_LOAD_FIT_FULL
-       select FIT_SIGNATURE
-       select SPL_FIT
-       select SPL_CRYPTO
-       select SPL_HASH
-       imply SPL_RSA
-       imply SPL_RSA_VERIFY
-       select SPL_IMAGE_SIGN_INFO
-       select SPL_FIT_FULL_CHECK
-
-config SPL_FIT_SIGNATURE_MAX_SIZE
-       hex "Max size of signed FIT structures in SPL"
-       depends on SPL_FIT_SIGNATURE
-       default 0x10000000
-       help
-         This option sets a max size in bytes for verified FIT uImages.
-         A sane value of 256MB protects corrupted DTB structures from overlapping
-         device memory. Assure this size does not extend past expected storage
-         space.
-
-config SPL_FIT_RSASSA_PSS
-       bool "Support rsassa-pss signature scheme of FIT image contents in SPL"
-       depends on SPL_FIT_SIGNATURE
-       help
-         Enable this to support the pss padding algorithm as described
-         in the rfc8017 (https://tools.ietf.org/html/rfc8017) in SPL.
-
-config SPL_LOAD_FIT
-       bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
-       select SPL_FIT
-       help
-         Normally with the SPL framework a legacy image is generated as part
-         of the build. This contains U-Boot along with information as to
-         where it should be loaded. This option instead enables generation
-         of a FIT (Flat Image Tree) which provides more flexibility. In
-         particular it can handle selecting from multiple device tree
-         and passing the correct one to U-Boot.
-
-         This path has the following limitations:
-
-         1. "loadables" images, other than FDTs, which do not have a "load"
-            property will not be loaded. This limitation also applies to FPGA
-            images with the correct "compatible" string.
-         2. For FPGA images, only the "compatible" = "u-boot,fpga-legacy"
-            loading method is supported.
-         3. FDTs are only loaded for images with an "os" property of "u-boot".
-            "linux" images are also supported with Falcon boot mode.
-
-config SPL_LOAD_FIT_ADDRESS
-       hex "load address of fit image"
-       depends on SPL_LOAD_FIT
-       default 0x0
-       help
-         Specify the load address of the fit image that will be loaded
-         by SPL.
-
-config SPL_LOAD_FIT_APPLY_OVERLAY
-       bool "Enable SPL applying DT overlays from FIT"
-       depends on SPL_LOAD_FIT
-       select OF_LIBFDT_OVERLAY
-       help
-         The device tree is loaded from the FIT image. Allow the SPL is to
-         also load device-tree overlays from the FIT image an apply them
-         over the device tree.
-
-config SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ
-       depends on SPL_LOAD_FIT_APPLY_OVERLAY
-       default 0x10000
-       hex "size of temporary buffer used to load the overlays"
-       help
-         The size of the area where the overlays will be loaded and
-         uncompress. Must be at least as large as biggest overlay
-         (uncompressed)
-
-config SPL_LOAD_FIT_FULL
-       bool "Enable SPL loading U-Boot as a FIT (full fitImage features)"
-       select SPL_FIT
-       help
-         Normally with the SPL framework a legacy image is generated as part
-         of the build. This contains U-Boot along with information as to
-         where it should be loaded. This option instead enables generation
-         of a FIT (Flat Image Tree) which provides more flexibility. In
-         particular it can handle selecting from multiple device tree
-         and passing the correct one to U-Boot.
-
-config SPL_FIT_IMAGE_POST_PROCESS
-       bool "Enable post-processing of FIT artifacts after loading by the SPL"
-       depends on SPL_LOAD_FIT
-       help
-         Allows doing any sort of manipulation to blobs after they got extracted
-         from the U-Boot FIT image like stripping off headers or modifying the
-         size of the blob, verification, authentication, decryption etc. in a
-         platform or board specific way. In order to use this feature a platform
-         or board-specific implementation of board_fit_image_post_process() must
-         be provided. Also, anything done during this post-processing step would
-         need to be comprehended in how the images were prepared before being
-         injected into the FIT creation (i.e. the blobs would have been pre-
-         processed before being added to the FIT image).
-
-config SPL_FIT_SOURCE
-       string ".its source file for U-Boot FIT image"
-       depends on SPL_FIT
-       help
-         Specifies a (platform specific) FIT source file to generate the
-         U-Boot FIT image. This could specify further image to load and/or
-         execute.
-
-config USE_SPL_FIT_GENERATOR
-       bool "Use a script to generate the .its script"
-       default y if SPL_FIT && (!ARCH_SUNXI && !RISCV)
-
-config SPL_FIT_GENERATOR
-       string ".its file generator script for U-Boot FIT image"
-       depends on USE_SPL_FIT_GENERATOR
-       default "arch/arm/mach-rockchip/make_fit_atf.py" if SPL_LOAD_FIT && ARCH_ROCKCHIP
-       default "arch/arm/mach-zynqmp/mkimage_fit_atf.sh" if SPL_LOAD_FIT && ARCH_ZYNQMP
-       help
-         Specifies a (platform specific) script file to generate the FIT
-         source file used to build the U-Boot FIT image file. This gets
-         passed a list of supported device tree file stub names to
-         include in the generated image.
-
-endif # SPL
-
-endif # FIT
-
-config LEGACY_IMAGE_FORMAT
-       bool "Enable support for the legacy image format"
-       default y if !FIT_SIGNATURE
-       help
-         This option enables the legacy image format. It is enabled by
-         default for backward compatibility, unless FIT_SIGNATURE is
-         set where it is disabled so that unsigned images cannot be
-         loaded. If a board needs the legacy image format support in this
-         case, enable it here.
-
-config SUPPORT_RAW_INITRD
-       bool "Enable raw initrd images"
-       help
-         Note, defining the SUPPORT_RAW_INITRD allows user to supply
-         kernel with raw initrd images. The syntax is slightly different, the
-         address of the initrd must be augmented by it's size, in the following
-         format: "<initrd address>:<initrd size>".
-
-config OF_BOARD_SETUP
-       bool "Set up board-specific details in device tree before boot"
-       depends on OF_LIBFDT
-       help
-         This causes U-Boot to call ft_board_setup() before booting into
-         the Operating System. This function can set up various
-         board-specific information in the device tree for use by the OS.
-         The device tree is then passed to the OS.
-
-config OF_SYSTEM_SETUP
-       bool "Set up system-specific details in device tree before boot"
-       depends on OF_LIBFDT
-       help
-         This causes U-Boot to call ft_system_setup() before booting into
-         the Operating System. This function can set up various
-         system-specific information in the device tree for use by the OS.
-         The device tree is then passed to the OS.
-
-config OF_STDOUT_VIA_ALIAS
-       bool "Update the device-tree stdout alias from U-Boot"
-       depends on OF_LIBFDT
-       help
-         This uses U-Boot's serial alias from the aliases node to update
-         the device tree passed to the OS. The "linux,stdout-path" property
-         in the chosen node is set to point to the correct serial node.
-         This option currently references CONFIG_CONS_INDEX, which is
-         incorrect when used with device tree as this option does not
-         exist / should not be used.
-
-config SYS_EXTRA_OPTIONS
-       string "Extra Options (DEPRECATED)"
-       help
-         The old configuration infrastructure (= mkconfig + boards.cfg)
-         provided the extra options field. If you have something like
-         "HAS_BAR,BAZ=64", the optional options
-           #define CONFIG_HAS
-           #define CONFIG_BAZ  64
-         will be defined in include/config.h.
-         This option was prepared for the smooth migration from the old
-         configuration to Kconfig. Since this option will be removed sometime,
-         new boards should not use this option.
-
-config HAVE_SYS_TEXT_BASE
-       bool
-       depends on !NIOS2 && !XTENSA
-       depends on !EFI_APP
-       default y
-
-config SYS_TEXT_BASE
-       depends on HAVE_SYS_TEXT_BASE
-       default 0x0 if POSITION_INDEPENDENT
-       default 0x80800000 if ARCH_OMAP2PLUS || ARCH_K3
-       default 0x4a000000 if ARCH_SUNXI && !MACH_SUN9I && !MACH_SUN8I_V3S
-       default 0x2a000000 if ARCH_SUNXI && MACH_SUN9I
-       default 0x42e00000 if ARCH_SUNXI && MACH_SUN8I_V3S
-       hex "Text Base"
-       help
-         The address in memory that U-Boot will be running from, initially.
-
-config SYS_CLK_FREQ
-       depends on ARC || ARCH_SUNXI || MPC83xx
-       int "CPU clock frequency"
-       help
-         TODO: Move CONFIG_SYS_CLK_FREQ for all the architecture
-
-config ARCH_FIXUP_FDT_MEMORY
-       bool "Enable arch_fixup_memory_banks() call"
-       default y
-       help
-         Enable FDT memory map syncup before OS boot. This feature can be
-         used for booting OS with different memory setup where the part of
-         the memory location should be used for different purpose.
-
-config CHROMEOS
-       bool "Support booting Chrome OS"
-       help
-         Chrome OS requires U-Boot to set up a table indicating the boot mode
-         (e.g. Developer mode) and a few other things. Enable this if you are
-         booting on a Chromebook to avoid getting an error about an invalid
-         firmware ID.
-
-config CHROMEOS_VBOOT
-       bool "Support Chrome OS verified boot"
-       help
-         This is intended to enable the full Chrome OS verified boot support
-         in U-Boot. It is not actually implemented in the U-Boot source code
-         at present, so this option is always set to 'n'. It allows
-         distinguishing between booting Chrome OS in a basic way (developer
-         mode) and a full boot.
-
-config RAMBOOT_PBL
-       bool "Freescale PBL(pre-boot loader) image format support"
-       help
-         Some SoCs use PBL to load RCW and/or pre-initialization instructions.
-         For more details refer to doc/README.pblimage
-
-config SYS_FSL_PBL_PBI
-       string "PBI(pre-boot instructions) commands for the PBL image"
-       depends on RAMBOOT_PBL
-       help
-         PBI commands can be used to configure SoC before it starts the execution.
-         Please refer doc/README.pblimage for more details.
-
-config SYS_FSL_PBL_RCW
-       string "Aadditional RCW (Power on reset configuration) for the PBL image"
-       depends on RAMBOOT_PBL
-       help
-         Enables addition of RCW (Power on reset configuration) in built image.
-         Please refer doc/README.pblimage for more details.
-
-endmenu                # Boot images
-
-menu "Boot timing"
-
-config BOOTSTAGE
-       bool "Boot timing and reporting"
-       help
-         Enable recording of boot time while booting. To use it, insert
-         calls to bootstage_mark() with a suitable BOOTSTAGE_ID from
-         bootstage.h. Only a single entry is recorded for each ID. You can
-         give the entry a name with bootstage_mark_name(). You can also
-         record elapsed time in a particular stage using bootstage_start()
-         before starting and bootstage_accum() when finished. Bootstage will
-         add up all the accumulated time and report it.
-
-         Normally, IDs are defined in bootstage.h but a small number of
-         additional 'user' IDs can be used by passing BOOTSTAGE_ID_ALLOC
-         as the ID.
-
-         Calls to show_boot_progress() will also result in log entries but
-         these will not have names.
-
-config SPL_BOOTSTAGE
-       bool "Boot timing and reported in SPL"
-       depends on BOOTSTAGE
-       help
-         Enable recording of boot time in SPL. To make this visible to U-Boot
-         proper, enable BOOTSTAGE_STASH as well. This will stash the timing
-         information when SPL finishes and load it when U-Boot proper starts
-         up.
-
-config TPL_BOOTSTAGE
-       bool "Boot timing and reported in TPL"
-       depends on BOOTSTAGE
-       help
-         Enable recording of boot time in SPL. To make this visible to U-Boot
-         proper, enable BOOTSTAGE_STASH as well. This will stash the timing
-         information when TPL finishes and load it when U-Boot proper starts
-         up.
-
-config BOOTSTAGE_REPORT
-       bool "Display a detailed boot timing report before booting the OS"
-       depends on BOOTSTAGE
-       help
-         Enable output of a boot time report just before the OS is booted.
-         This shows how long it took U-Boot to go through each stage of the
-         boot process. The report looks something like this:
-
-               Timer summary in microseconds:
-                      Mark    Elapsed  Stage
-                         0          0  reset
-                 3,575,678  3,575,678  board_init_f start
-                 3,575,695         17  arch_cpu_init A9
-                 3,575,777         82  arch_cpu_init done
-                 3,659,598     83,821  board_init_r start
-                 3,910,375    250,777  main_loop
-                29,916,167 26,005,792  bootm_start
-                30,361,327    445,160  start_kernel
-
-config BOOTSTAGE_RECORD_COUNT
-       int "Number of boot stage records to store"
-       depends on BOOTSTAGE
-       default 30
-       help
-         This is the size of the bootstage record list and is the maximum
-         number of bootstage records that can be recorded.
-
-config SPL_BOOTSTAGE_RECORD_COUNT
-       int "Number of boot stage records to store for SPL"
-       depends on SPL_BOOTSTAGE
-       default 5
-       help
-         This is the size of the bootstage record list and is the maximum
-         number of bootstage records that can be recorded.
-
-config TPL_BOOTSTAGE_RECORD_COUNT
-       int "Number of boot stage records to store for TPL"
-       depends on TPL_BOOTSTAGE
-       default 5
-       help
-         This is the size of the bootstage record list and is the maximum
-         number of bootstage records that can be recorded.
-
-config BOOTSTAGE_FDT
-       bool "Store boot timing information in the OS device tree"
-       depends on BOOTSTAGE
-       help
-         Stash the bootstage information in the FDT. A root 'bootstage'
-         node is created with each bootstage id as a child. Each child
-         has a 'name' property and either 'mark' containing the
-         mark time in microseconds, or 'accum' containing the
-         accumulated time for that bootstage id in microseconds.
-         For example:
-
-               bootstage {
-                       154 {
-                               name = "board_init_f";
-                               mark = <3575678>;
-                       };
-                       170 {
-                               name = "lcd";
-                               accum = <33482>;
-                       };
-               };
-
-         Code in the Linux kernel can find this in /proc/devicetree.
-
-config BOOTSTAGE_STASH
-       bool "Stash the boot timing information in memory before booting OS"
-       depends on BOOTSTAGE
-       help
-         Some OSes do not support device tree. Bootstage can instead write
-         the boot timing information in a binary format at a given address.
-         This happens through a call to bootstage_stash(), typically in
-         the CPU's cleanup_before_linux() function. You can use the
-         'bootstage stash' and 'bootstage unstash' commands to do this on
-         the command line.
-
-config BOOTSTAGE_STASH_ADDR
-       hex "Address to stash boot timing information"
-       default 0
-       help
-         Provide an address which will not be overwritten by the OS when it
-         starts, so that it can read this information when ready.
-
-config BOOTSTAGE_STASH_SIZE
-       hex "Size of boot timing stash region"
-       default 0x1000
-       help
-         This should be large enough to hold the bootstage stash. A value of
-         4096 (4KiB) is normally plenty.
-
-config SHOW_BOOT_PROGRESS
-       bool "Show boot progress in a board-specific manner"
-       help
-         Defining this option allows to add some board-specific code (calling
-         a user-provided function show_boot_progress(int) that enables you to
-         show the system's boot progress on some display (for example, some
-         LEDs) on your board. At the moment, the following checkpoints are
-         implemented:
-
-         Legacy uImage format:
-
-         Arg   Where                   When
-           1   common/cmd_bootm.c      before attempting to boot an image
-          -1   common/cmd_bootm.c      Image header has bad     magic number
-           2   common/cmd_bootm.c      Image header has correct magic number
-          -2   common/cmd_bootm.c      Image header has bad     checksum
-           3   common/cmd_bootm.c      Image header has correct checksum
-          -3   common/cmd_bootm.c      Image data   has bad     checksum
-           4   common/cmd_bootm.c      Image data   has correct checksum
-          -4   common/cmd_bootm.c      Image is for unsupported architecture
-           5   common/cmd_bootm.c      Architecture check OK
-          -5   common/cmd_bootm.c      Wrong Image Type (not kernel, multi)
-           6   common/cmd_bootm.c      Image Type check OK
-          -6   common/cmd_bootm.c      gunzip uncompression error
-          -7   common/cmd_bootm.c      Unimplemented compression type
-           7   common/cmd_bootm.c      Uncompression OK
-           8   common/cmd_bootm.c      No uncompress/copy overwrite error
-          -9   common/cmd_bootm.c      Unsupported OS (not Linux, BSD, VxWorks, QNX)
-
-           9   common/image.c          Start initial ramdisk verification
-         -10   common/image.c          Ramdisk header has bad     magic number
-         -11   common/image.c          Ramdisk header has bad     checksum
-          10   common/image.c          Ramdisk header is OK
-         -12   common/image.c          Ramdisk data   has bad     checksum
-          11   common/image.c          Ramdisk data   has correct checksum
-          12   common/image.c          Ramdisk verification complete, start loading
-         -13   common/image.c          Wrong Image Type (not PPC Linux ramdisk)
-          13   common/image.c          Start multifile image verification
-          14   common/image.c          No initial ramdisk, no multifile, continue.
-
-          15   arch/<arch>/lib/bootm.c All preparation done, transferring control to OS
-
-         -30   arch/powerpc/lib/board.c        Fatal error, hang the system
-         -31   post/post.c             POST test failed, detected by post_output_backlog()
-         -32   post/post.c             POST test failed, detected by post_run_single()
-
-          34   common/cmd_doc.c        before loading a Image from a DOC device
-         -35   common/cmd_doc.c        Bad usage of "doc" command
-          35   common/cmd_doc.c        correct usage of "doc" command
-         -36   common/cmd_doc.c        No boot device
-          36   common/cmd_doc.c        correct boot device
-         -37   common/cmd_doc.c        Unknown Chip ID on boot device
-          37   common/cmd_doc.c        correct chip ID found, device available
-         -38   common/cmd_doc.c        Read Error on boot device
-          38   common/cmd_doc.c        reading Image header from DOC device OK
-         -39   common/cmd_doc.c        Image header has bad magic number
-          39   common/cmd_doc.c        Image header has correct magic number
-         -40   common/cmd_doc.c        Error reading Image from DOC device
-          40   common/cmd_doc.c        Image header has correct magic number
-          41   common/cmd_ide.c        before loading a Image from a IDE device
-         -42   common/cmd_ide.c        Bad usage of "ide" command
-          42   common/cmd_ide.c        correct usage of "ide" command
-         -43   common/cmd_ide.c        No boot device
-          43   common/cmd_ide.c        boot device found
-         -44   common/cmd_ide.c        Device not available
-          44   common/cmd_ide.c        Device available
-         -45   common/cmd_ide.c        wrong partition selected
-          45   common/cmd_ide.c        partition selected
-         -46   common/cmd_ide.c        Unknown partition table
-          46   common/cmd_ide.c        valid partition table found
-         -47   common/cmd_ide.c        Invalid partition type
-          47   common/cmd_ide.c        correct partition type
-         -48   common/cmd_ide.c        Error reading Image Header on boot device
-          48   common/cmd_ide.c        reading Image Header from IDE device OK
-         -49   common/cmd_ide.c        Image header has bad magic number
-          49   common/cmd_ide.c        Image header has correct magic number
-         -50   common/cmd_ide.c        Image header has bad     checksum
-          50   common/cmd_ide.c        Image header has correct checksum
-         -51   common/cmd_ide.c        Error reading Image from IDE device
-          51   common/cmd_ide.c        reading Image from IDE device OK
-          52   common/cmd_nand.c       before loading a Image from a NAND device
-         -53   common/cmd_nand.c       Bad usage of "nand" command
-          53   common/cmd_nand.c       correct usage of "nand" command
-         -54   common/cmd_nand.c       No boot device
-          54   common/cmd_nand.c       boot device found
-         -55   common/cmd_nand.c       Unknown Chip ID on boot device
-          55   common/cmd_nand.c       correct chip ID found, device available
-         -56   common/cmd_nand.c       Error reading Image Header on boot device
-          56   common/cmd_nand.c       reading Image Header from NAND device OK
-         -57   common/cmd_nand.c       Image header has bad magic number
-          57   common/cmd_nand.c       Image header has correct magic number
-         -58   common/cmd_nand.c       Error reading Image from NAND device
-          58   common/cmd_nand.c       reading Image from NAND device OK
-
-         -60   common/env_common.c     Environment has a bad CRC, using default
-
-          64   net/eth.c               starting with Ethernet configuration.
-         -64   net/eth.c               no Ethernet found.
-          65   net/eth.c               Ethernet found.
-
-         -80   common/cmd_net.c        usage wrong
-          80   common/cmd_net.c        before calling net_loop()
-         -81   common/cmd_net.c        some error in net_loop() occurred
-          81   common/cmd_net.c        net_loop() back without error
-         -82   common/cmd_net.c        size == 0 (File with size 0 loaded)
-          82   common/cmd_net.c        trying automatic boot
-          83   common/cmd_net.c        running "source" command
-         -83   common/cmd_net.c        some error in automatic boot or "source" command
-          84   common/cmd_net.c        end without errors
-
-         FIT uImage format:
-
-         Arg   Where                   When
-         100   common/cmd_bootm.c      Kernel FIT Image has correct format
-         -100  common/cmd_bootm.c      Kernel FIT Image has incorrect format
-         101   common/cmd_bootm.c      No Kernel subimage unit name, using configuration
-         -101  common/cmd_bootm.c      Can't get configuration for kernel subimage
-         102   common/cmd_bootm.c      Kernel unit name specified
-         -103  common/cmd_bootm.c      Can't get kernel subimage node offset
-         103   common/cmd_bootm.c      Found configuration node
-         104   common/cmd_bootm.c      Got kernel subimage node offset
-         -104  common/cmd_bootm.c      Kernel subimage hash verification failed
-         105   common/cmd_bootm.c      Kernel subimage hash verification OK
-         -105  common/cmd_bootm.c      Kernel subimage is for unsupported architecture
-         106   common/cmd_bootm.c      Architecture check OK
-         -106  common/cmd_bootm.c      Kernel subimage has wrong type
-         107   common/cmd_bootm.c      Kernel subimage type OK
-         -107  common/cmd_bootm.c      Can't get kernel subimage data/size
-         108   common/cmd_bootm.c      Got kernel subimage data/size
-         -108  common/cmd_bootm.c      Wrong image type (not legacy, FIT)
-         -109  common/cmd_bootm.c      Can't get kernel subimage type
-         -110  common/cmd_bootm.c      Can't get kernel subimage comp
-         -111  common/cmd_bootm.c      Can't get kernel subimage os
-         -112  common/cmd_bootm.c      Can't get kernel subimage load address
-         -113  common/cmd_bootm.c      Image uncompress/copy overwrite error
-
-         120   common/image.c          Start initial ramdisk verification
-         -120  common/image.c          Ramdisk FIT image has incorrect format
-         121   common/image.c          Ramdisk FIT image has correct format
-         122   common/image.c          No ramdisk subimage unit name, using configuration
-         -122  common/image.c          Can't get configuration for ramdisk subimage
-         123   common/image.c          Ramdisk unit name specified
-         -124  common/image.c          Can't get ramdisk subimage node offset
-         125   common/image.c          Got ramdisk subimage node offset
-         -125  common/image.c          Ramdisk subimage hash verification failed
-         126   common/image.c          Ramdisk subimage hash verification OK
-         -126  common/image.c          Ramdisk subimage for unsupported architecture
-         127   common/image.c          Architecture check OK
-         -127  common/image.c          Can't get ramdisk subimage data/size
-         128   common/image.c          Got ramdisk subimage data/size
-         129   common/image.c          Can't get ramdisk load address
-         -129  common/image.c          Got ramdisk load address
-
-         -130  common/cmd_doc.c        Incorrect FIT image format
-         131   common/cmd_doc.c        FIT image format OK
-
-         -140  common/cmd_ide.c        Incorrect FIT image format
-         141   common/cmd_ide.c        FIT image format OK
-
-         -150  common/cmd_nand.c       Incorrect FIT image format
-         151   common/cmd_nand.c       FIT image format OK
-
-config SPL_SHOW_BOOT_PROGRESS
-       bool "Show boot progress in a board-specific manner"
-       depends on SPL
-       help
-         Defining this option allows to add some board-specific code (calling
-         a user-provided function show_boot_progress(int) that enables you to
-         show the system's boot progress on some display (for example, some
-         LEDs) on your board. For details see SHOW_BOOT_PROGRESS.
-
-endmenu
-
-menu "Boot media"
-
-config NOR_BOOT
-       bool "Support for booting from NOR flash"
-       depends on NOR
-       help
-         Enabling this will make a U-Boot binary that is capable of being
-         booted via NOR.  In this case we will enable certain pinmux early
-         as the ROM only partially sets up pinmux.  We also default to using
-         NOR for environment.
-
-config NAND_BOOT
-       bool "Support for booting from NAND flash"
-       imply MTD_RAW_NAND
-       help
-         Enabling this will make a U-Boot binary that is capable of being
-         booted via NAND flash. This is not a must, some SoCs need this,
-         some not.
-
-config ONENAND_BOOT
-       bool "Support for booting from ONENAND"
-       imply MTD_RAW_NAND
-       help
-         Enabling this will make a U-Boot binary that is capable of being
-         booted via ONENAND. This is not a must, some SoCs need this,
-         some not.
-
-config QSPI_BOOT
-       bool "Support for booting from QSPI flash"
-       help
-         Enabling this will make a U-Boot binary that is capable of being
-         booted via QSPI flash. This is not a must, some SoCs need this,
-         some not.
-
-config SATA_BOOT
-       bool "Support for booting from SATA"
-       help
-         Enabling this will make a U-Boot binary that is capable of being
-         booted via SATA. This is not a must, some SoCs need this,
-         some not.
-
-config SD_BOOT
-       bool "Support for booting from SD/EMMC"
-       help
-         Enabling this will make a U-Boot binary that is capable of being
-         booted via SD/EMMC. This is not a must, some SoCs need this,
-         some not.
-
-config SPI_BOOT
-       bool "Support for booting from SPI flash"
-       help
-         Enabling this will make a U-Boot binary that is capable of being
-         booted via SPI flash. This is not a must, some SoCs need this,
-         some not.
-
-endmenu
-
-menu "Autoboot options"
-
-config AUTOBOOT
-       bool "Autoboot"
-       default y
-       help
-         This enables the autoboot.  See doc/README.autoboot for detail.
-
-config BOOTDELAY
-       int "delay in seconds before automatically booting"
-       default 2
-       depends on AUTOBOOT
-       help
-         Delay before automatically running bootcmd;
-         set to 0 to autoboot with no delay, but you can stop it by key input.
-         set to -1 to disable autoboot.
-         set to -2 to autoboot with no delay and not check for abort
-
-         If this value is >= 0 then it is also used for the default delay
-         before starting the default entry in bootmenu. If it is < 0 then
-         a default value of 10s is used.
-
-         See doc/README.autoboot for details.
-
-config AUTOBOOT_KEYED
-       bool "Stop autobooting via specific input key / string"
-       help
-         This option enables stopping (aborting) of the automatic
-         boot feature only by issuing a specific input key or
-         string. If not enabled, any input key will abort the
-         U-Boot automatic booting process and bring the device
-         to the U-Boot prompt for user input.
-
-config AUTOBOOT_FLUSH_STDIN
-       bool "Enable flushing stdin before starting to read the password"
-       depends on AUTOBOOT_KEYED && !SANDBOX
-       help
-         When this option is enabled stdin buffer will be flushed before
-         starting to read the password.
-         This can't be enabled for the sandbox as flushing stdin would
-         break the autoboot unit tests.
-
-config AUTOBOOT_PROMPT
-       string "Autoboot stop prompt"
-       depends on AUTOBOOT_KEYED
-       default "Autoboot in %d seconds\\n"
-       help
-         This string is displayed before the boot delay selected by
-         CONFIG_BOOTDELAY starts. If it is not defined there is no
-         output indicating that autoboot is in progress.
-
-         Note that this define is used as the (only) argument to a
-         printf() call, so it may contain '%' format specifications,
-         provided that it also includes, sepearated by commas exactly
-         like in a printf statement, the required arguments. It is
-         the responsibility of the user to select only such arguments
-         that are valid in the given context.
-
-config AUTOBOOT_ENCRYPTION
-       bool "Enable encryption in autoboot stopping"
-       depends on AUTOBOOT_KEYED
-       help
-         This option allows a string to be entered into U-Boot to stop the
-         autoboot.
-         The behavior depends whether CONFIG_CRYPT_PW from lib is enabled
-         or not.
-         In case CONFIG_CRYPT_PW is enabled, the string will be forwarded
-         to the crypt-based functionality and be compared against the
-         string in the environment variable 'bootstopkeycrypt'.
-         In case CONFIG_CRYPT_PW is disabled the string itself is hashed
-         and compared against the hash in the environment variable
-         'bootstopkeysha256'.
-         If it matches in either case then boot stops and
-         a command-line prompt is presented.
-         This provides a way to ship a secure production device which can also
-         be accessed at the U-Boot command line.
-
-config AUTOBOOT_SHA256_FALLBACK
-       bool "Allow fallback from crypt-hashed password to sha256"
-       depends on AUTOBOOT_ENCRYPTION && CRYPT_PW
-       help
-         This option adds support to fall back from crypt-hashed
-         passwords to checking a SHA256 hashed password in case the
-         'bootstopusesha256' environment variable is set to 'true'.
-
-config AUTOBOOT_DELAY_STR
-       string "Delay autobooting via specific input key / string"
-       depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION
-       help
-         This option delays the automatic boot feature by issuing
-         a specific input key or string. If CONFIG_AUTOBOOT_DELAY_STR
-         or the environment variable "bootdelaykey" is specified
-         and this string is received from console input before
-         autoboot starts booting, U-Boot gives a command prompt. The
-         U-Boot prompt will time out if CONFIG_BOOT_RETRY_TIME is
-         used, otherwise it never times out.
-
-config AUTOBOOT_STOP_STR
-       string "Stop autobooting via specific input key / string"
-       depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION
-       help
-         This option enables stopping (aborting) of the automatic
-         boot feature only by issuing a specific input key or
-         string. If CONFIG_AUTOBOOT_STOP_STR or the environment
-         variable "bootstopkey" is specified and this string is
-         received from console input before autoboot starts booting,
-         U-Boot gives a command prompt. The U-Boot prompt never
-         times out, even if CONFIG_BOOT_RETRY_TIME is used.
-
-config AUTOBOOT_KEYED_CTRLC
-       bool "Enable Ctrl-C autoboot interruption"
-       depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION
-       help
-         This option allows for the boot sequence to be interrupted
-         by ctrl-c, in addition to the "bootdelaykey" and "bootstopkey".
-         Setting this variable provides an escape sequence from the
-         limited "password" strings.
-
-config AUTOBOOT_NEVER_TIMEOUT
-       bool "Make the password entry never time-out"
-       depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION && CRYPT_PW
-       help
-         This option removes the timeout from the password entry
-         when the user first presses the <Enter> key before entering
-         any other character.
-
-config AUTOBOOT_STOP_STR_ENABLE
-       bool "Enable fixed string to stop autobooting"
-       depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION
-       help
-         This option enables the feature to add a fixed stop
-         string that is defined at compile time.
-         In every case it will be tried to load the stop
-         string from the environment.
-         In case this is enabled and there is no stop string
-         in the environment, this will be used as default value.
-
-config AUTOBOOT_STOP_STR_CRYPT
-       string "Stop autobooting via crypt-hashed password"
-       depends on AUTOBOOT_STOP_STR_ENABLE && CRYPT_PW
-       help
-         This option adds the feature to only stop the autobooting,
-         and therefore boot into the U-Boot prompt, when the input
-         string / password matches a values that is hashed via
-         one of the supported crypt-style password hashing options
-         and saved in the environment variable "bootstopkeycrypt".
-
-config AUTOBOOT_STOP_STR_SHA256
-       string "Stop autobooting via SHA256 hashed password"
-       depends on AUTOBOOT_STOP_STR_ENABLE
-       help
-         This option adds the feature to only stop the autobooting,
-         and therefore boot into the U-Boot prompt, when the input
-         string / password matches a values that is encypted via
-         a SHA256 hash and saved in the environment variable
-         "bootstopkeysha256". If the value in that variable
-         includes a ":", the portion prior to the ":" will be treated
-         as a salt value.
-
-config AUTOBOOT_USE_MENUKEY
-       bool "Allow a specify key to run a menu from the environment"
-       depends on !AUTOBOOT_KEYED
-       help
-         If a specific key is pressed to stop autoboot, then the commands in
-         the environment variable 'menucmd' are executed before boot starts.
-
-config AUTOBOOT_MENUKEY
-       int "ASCII value of boot key to show a menu"
-       default 0
-       depends on AUTOBOOT_USE_MENUKEY
-       help
-         If this key is pressed to stop autoboot, then the commands in the
-         environment variable 'menucmd' will be executed before boot starts.
-         For example, 33 means "!" in ASCII, so pressing ! at boot would take
-         this action.
-
-config AUTOBOOT_MENU_SHOW
-       bool "Show a menu on boot"
-       depends on CMD_BOOTMENU
-       help
-         This enables the boot menu, controlled by environment variables
-         defined by the board. The menu starts after running the 'preboot'
-         environmnent variable (if enabled) and before handling the boot delay.
-         See README.bootmenu for more details.
-
-endmenu
-
-config USE_BOOTARGS
-       bool "Enable boot arguments"
-       help
-         Provide boot arguments to bootm command. Boot arguments are specified
-         in CONFIG_BOOTARGS option. Enable this option to be able to specify
-         CONFIG_BOOTARGS string. If this option is disabled, CONFIG_BOOTARGS
-         will be undefined and won't take any space in U-Boot image.
-
-config BOOTARGS
-       string "Boot arguments"
-       depends on USE_BOOTARGS && !USE_DEFAULT_ENV_FILE
-       help
-         This can be used to pass arguments to the bootm command. The value of
-         CONFIG_BOOTARGS goes into the environment value "bootargs". Note that
-         this value will also override the "chosen" node in FDT blob.
-
-config BOOTARGS_SUBST
-       bool "Support substituting strings in boot arguments"
-       help
-         This allows substituting string values in the boot arguments. These
-         are applied after the commandline has been built.
-
-         One use for this is to insert the root-disk UUID into the command
-         line where bootargs contains "root=${uuid}"
-
-               setenv bootargs "console= root=${uuid}"
-               # Set the 'uuid' environment variable
-               part uuid mmc 2:2 uuid
-
-               # Command-line substitution will put the real uuid into the
-               # kernel command line
-               bootm
-
-config USE_BOOTCOMMAND
-       bool "Enable a default value for bootcmd"
-       help
-         Provide a default value for the bootcmd entry in the environment.  If
-         autoboot is enabled this is what will be run automatically.  Enable
-         this option to be able to specify CONFIG_BOOTCOMMAND as a string.  If
-         this option is disabled, CONFIG_BOOTCOMMAND will be undefined and
-         won't take any space in U-Boot image.
-
-config BOOTCOMMAND
-       string "bootcmd value"
-       depends on USE_BOOTCOMMAND && !USE_DEFAULT_ENV_FILE
-       default "run distro_bootcmd" if DISTRO_DEFAULTS
-       help
-         This is the string of commands that will be used as bootcmd and if
-         AUTOBOOT is set, automatically run.
-
-config USE_PREBOOT
-       bool "Enable preboot"
-       help
-         When this option is enabled, the existence of the environment
-         variable "preboot" will be checked immediately before starting the
-         CONFIG_BOOTDELAY countdown and/or running the auto-boot command resp.
-         entering interactive mode.
-
-         This feature is especially useful when "preboot" is automatically
-         generated or modified. For example, the boot code can modify the
-         "preboot" when a user holds down a certain combination of keys.
-
-config PREBOOT
-       string "preboot default value"
-       depends on USE_PREBOOT && !USE_DEFAULT_ENV_FILE
-       default "usb start" if USB_KEYBOARD
-       default ""
-       help
-         This is the default of "preboot" environment variable.
-
-config DEFAULT_FDT_FILE
-       string "Default fdt file"
-       help
-         This option is used to set the default fdt file to boot OS.
-
-endmenu                # Booting
index e7839027b6cf704579322a59c1548a6a0978448f..afaf8e5048ae4381c50f086447592566cfa19021 100644 (file)
@@ -11,21 +11,12 @@ obj-y += exports.o
 obj-$(CONFIG_HUSH_PARSER) += cli_hush.o
 obj-$(CONFIG_AUTOBOOT) += autoboot.o
 
-# This option is not just y/n - it can have a numeric value
-ifdef CONFIG_BOOT_RETRY_TIME
-obj-y += bootretry.o
-endif
-
 # # boards
 obj-y += board_f.o
 obj-y += board_r.o
 obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
 obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o
 
-obj-$(CONFIG_CMD_BOOTM) += bootm.o bootm_os.o
-obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o
-obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
-
 obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
 obj-$(CONFIG_MII) += miiphyutil.o
@@ -65,7 +56,6 @@ ifdef CONFIG_SPL_BUILD
 ifdef CONFIG_SPL_DFU
 obj-$(CONFIG_DFU_OVER_USB) += dfu.o
 endif
-obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
 obj-$(CONFIG_SPL_NET) += miiphyutil.o
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
 
@@ -101,23 +91,11 @@ obj-y += malloc_simple.o
 endif
 endif
 
-obj-y += image.o image-board.o
 obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o
-obj-$(CONFIG_ANDROID_AB) += android_ab.o
-obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
-obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
-obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += fdt_region.o
-obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
-obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
-obj-$(CONFIG_$(SPL_TPL_)IMAGE_SIGN_INFO) += image-sig.o
-obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-fit-sig.o
-obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o
 obj-$(CONFIG_IO_TRACE) += iotrace.o
 obj-y += memsize.o
 obj-y += stdio.o
 
-obj-$(CONFIG_CMD_ADTIMG) += image-android-dt.o
-
 ifdef CONFIG_CMD_EEPROM_LAYOUT
 obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
 endif
diff --git a/common/android_ab.c b/common/android_ab.c
deleted file mode 100644 (file)
index 4943f26..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-// SPDX-License-Identifier: BSD-2-Clause
-/*
- * Copyright (C) 2017 The Android Open Source Project
- */
-#include <common.h>
-#include <android_ab.h>
-#include <android_bootloader_message.h>
-#include <blk.h>
-#include <log.h>
-#include <malloc.h>
-#include <part.h>
-#include <memalign.h>
-#include <linux/err.h>
-#include <u-boot/crc.h>
-#include <u-boot/crc.h>
-
-/**
- * Compute the CRC-32 of the bootloader control struct.
- *
- * Only the bytes up to the crc32_le field are considered for the CRC-32
- * calculation.
- *
- * @param[in] abc bootloader control block
- *
- * @return crc32 sum
- */
-static uint32_t ab_control_compute_crc(struct bootloader_control *abc)
-{
-       return crc32(0, (void *)abc, offsetof(typeof(*abc), crc32_le));
-}
-
-/**
- * Initialize bootloader_control to the default value.
- *
- * It allows us to boot all slots in order from the first one. This value
- * should be used when the bootloader message is corrupted, but not when
- * a valid message indicates that all slots are unbootable.
- *
- * @param[in] abc bootloader control block
- *
- * @return 0 on success and a negative on error
- */
-static int ab_control_default(struct bootloader_control *abc)
-{
-       int i;
-       const struct slot_metadata metadata = {
-               .priority = 15,
-               .tries_remaining = 7,
-               .successful_boot = 0,
-               .verity_corrupted = 0,
-               .reserved = 0
-       };
-
-       if (!abc)
-               return -EFAULT;
-
-       memcpy(abc->slot_suffix, "a\0\0\0", 4);
-       abc->magic = BOOT_CTRL_MAGIC;
-       abc->version = BOOT_CTRL_VERSION;
-       abc->nb_slot = NUM_SLOTS;
-       memset(abc->reserved0, 0, sizeof(abc->reserved0));
-       for (i = 0; i < abc->nb_slot; ++i)
-               abc->slot_info[i] = metadata;
-
-       memset(abc->reserved1, 0, sizeof(abc->reserved1));
-       abc->crc32_le = ab_control_compute_crc(abc);
-
-       return 0;
-}
-
-/**
- * Load the boot_control struct from disk into newly allocated memory.
- *
- * This function allocates and returns an integer number of disk blocks,
- * based on the block size of the passed device to help performing a
- * read-modify-write operation on the boot_control struct.
- * The boot_control struct offset (2 KiB) must be a multiple of the device
- * block size, for simplicity.
- *
- * @param[in] dev_desc Device where to read the boot_control struct from
- * @param[in] part_info Partition in 'dev_desc' where to read from, normally
- *                     the "misc" partition should be used
- * @param[out] pointer to pointer to bootloader_control data
- * @return 0 on success and a negative on error
- */
-static int ab_control_create_from_disk(struct blk_desc *dev_desc,
-                                      const struct disk_partition *part_info,
-                                      struct bootloader_control **abc)
-{
-       ulong abc_offset, abc_blocks, ret;
-
-       abc_offset = offsetof(struct bootloader_message_ab, slot_suffix);
-       if (abc_offset % part_info->blksz) {
-               log_err("ANDROID: Boot control block not block aligned.\n");
-               return -EINVAL;
-       }
-       abc_offset /= part_info->blksz;
-
-       abc_blocks = DIV_ROUND_UP(sizeof(struct bootloader_control),
-                                 part_info->blksz);
-       if (abc_offset + abc_blocks > part_info->size) {
-               log_err("ANDROID: boot control partition too small. Need at");
-               log_err(" least %lu blocks but have %lu blocks.\n",
-                       abc_offset + abc_blocks, part_info->size);
-               return -EINVAL;
-       }
-       *abc = malloc_cache_aligned(abc_blocks * part_info->blksz);
-       if (!*abc)
-               return -ENOMEM;
-
-       ret = blk_dread(dev_desc, part_info->start + abc_offset, abc_blocks,
-                       *abc);
-       if (IS_ERR_VALUE(ret)) {
-               log_err("ANDROID: Could not read from boot ctrl partition\n");
-               free(*abc);
-               return -EIO;
-       }
-
-       log_debug("ANDROID: Loaded ABC, %lu blocks\n", abc_blocks);
-
-       return 0;
-}
-
-/**
- * Store the loaded boot_control block.
- *
- * Store back to the same location it was read from with
- * ab_control_create_from_misc().
- *
- * @param[in] dev_desc Device where we should write the boot_control struct
- * @param[in] part_info Partition on the 'dev_desc' where to write
- * @param[in] abc Pointer to the boot control struct and the extra bytes after
- *                it up to the nearest block boundary
- * @return 0 on success and a negative on error
- */
-static int ab_control_store(struct blk_desc *dev_desc,
-                           const struct disk_partition *part_info,
-                           struct bootloader_control *abc)
-{
-       ulong abc_offset, abc_blocks, ret;
-
-       abc_offset = offsetof(struct bootloader_message_ab, slot_suffix) /
-                    part_info->blksz;
-       abc_blocks = DIV_ROUND_UP(sizeof(struct bootloader_control),
-                                 part_info->blksz);
-       ret = blk_dwrite(dev_desc, part_info->start + abc_offset, abc_blocks,
-                        abc);
-       if (IS_ERR_VALUE(ret)) {
-               log_err("ANDROID: Could not write back the misc partition\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/**
- * Compare two slots.
- *
- * The function determines slot which is should we boot from among the two.
- *
- * @param[in] a The first bootable slot metadata
- * @param[in] b The second bootable slot metadata
- * @return Negative if the slot "a" is better, positive of the slot "b" is
- *         better or 0 if they are equally good.
- */
-static int ab_compare_slots(const struct slot_metadata *a,
-                           const struct slot_metadata *b)
-{
-       /* Higher priority is better */
-       if (a->priority != b->priority)
-               return b->priority - a->priority;
-
-       /* Higher successful_boot value is better, in case of same priority */
-       if (a->successful_boot != b->successful_boot)
-               return b->successful_boot - a->successful_boot;
-
-       /* Higher tries_remaining is better to ensure round-robin */
-       if (a->tries_remaining != b->tries_remaining)
-               return b->tries_remaining - a->tries_remaining;
-
-       return 0;
-}
-
-int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info)
-{
-       struct bootloader_control *abc = NULL;
-       u32 crc32_le;
-       int slot, i, ret;
-       bool store_needed = false;
-       char slot_suffix[4];
-
-       ret = ab_control_create_from_disk(dev_desc, part_info, &abc);
-       if (ret < 0) {
-               /*
-                * This condition represents an actual problem with the code or
-                * the board setup, like an invalid partition information.
-                * Signal a repair mode and do not try to boot from either slot.
-                */
-               return ret;
-       }
-
-       crc32_le = ab_control_compute_crc(abc);
-       if (abc->crc32_le != crc32_le) {
-               log_err("ANDROID: Invalid CRC-32 (expected %.8x, found %.8x),",
-                       crc32_le, abc->crc32_le);
-               log_err("re-initializing A/B metadata.\n");
-
-               ret = ab_control_default(abc);
-               if (ret < 0) {
-                       free(abc);
-                       return -ENODATA;
-               }
-               store_needed = true;
-       }
-
-       if (abc->magic != BOOT_CTRL_MAGIC) {
-               log_err("ANDROID: Unknown A/B metadata: %.8x\n", abc->magic);
-               free(abc);
-               return -ENODATA;
-       }
-
-       if (abc->version > BOOT_CTRL_VERSION) {
-               log_err("ANDROID: Unsupported A/B metadata version: %.8x\n",
-                       abc->version);
-               free(abc);
-               return -ENODATA;
-       }
-
-       /*
-        * At this point a valid boot control metadata is stored in abc,
-        * followed by other reserved data in the same block. We select a with
-        * the higher priority slot that
-        *  - is not marked as corrupted and
-        *  - either has tries_remaining > 0 or successful_boot is true.
-        * If the selected slot has a false successful_boot, we also decrement
-        * the tries_remaining until it eventually becomes unbootable because
-        * tries_remaining reaches 0. This mechanism produces a bootloader
-        * induced rollback, typically right after a failed update.
-        */
-
-       /* Safety check: limit the number of slots. */
-       if (abc->nb_slot > ARRAY_SIZE(abc->slot_info)) {
-               abc->nb_slot = ARRAY_SIZE(abc->slot_info);
-               store_needed = true;
-       }
-
-       slot = -1;
-       for (i = 0; i < abc->nb_slot; ++i) {
-               if (abc->slot_info[i].verity_corrupted ||
-                   !abc->slot_info[i].tries_remaining) {
-                       log_debug("ANDROID: unbootable slot %d tries: %d, ",
-                                 i, abc->slot_info[i].tries_remaining);
-                       log_debug("corrupt: %d\n",
-                                 abc->slot_info[i].verity_corrupted);
-                       continue;
-               }
-               log_debug("ANDROID: bootable slot %d pri: %d, tries: %d, ",
-                         i, abc->slot_info[i].priority,
-                         abc->slot_info[i].tries_remaining);
-               log_debug("corrupt: %d, successful: %d\n",
-                         abc->slot_info[i].verity_corrupted,
-                         abc->slot_info[i].successful_boot);
-
-               if (slot < 0 ||
-                   ab_compare_slots(&abc->slot_info[i],
-                                    &abc->slot_info[slot]) < 0) {
-                       slot = i;
-               }
-       }
-
-       if (slot >= 0 && !abc->slot_info[slot].successful_boot) {
-               log_err("ANDROID: Attempting slot %c, tries remaining %d\n",
-                       BOOT_SLOT_NAME(slot),
-                       abc->slot_info[slot].tries_remaining);
-               abc->slot_info[slot].tries_remaining--;
-               store_needed = true;
-       }
-
-       if (slot >= 0) {
-               /*
-                * Legacy user-space requires this field to be set in the BCB.
-                * Newer releases load this slot suffix from the command line
-                * or the device tree.
-                */
-               memset(slot_suffix, 0, sizeof(slot_suffix));
-               slot_suffix[0] = BOOT_SLOT_NAME(slot);
-               if (memcmp(abc->slot_suffix, slot_suffix,
-                          sizeof(slot_suffix))) {
-                       memcpy(abc->slot_suffix, slot_suffix,
-                              sizeof(slot_suffix));
-                       store_needed = true;
-               }
-       }
-
-       if (store_needed) {
-               abc->crc32_le = ab_control_compute_crc(abc);
-               ab_control_store(dev_desc, part_info, abc);
-       }
-       free(abc);
-
-       if (slot < 0)
-               return -EINVAL;
-
-       return slot;
-}
diff --git a/common/boot_fit.c b/common/boot_fit.c
deleted file mode 100644 (file)
index dfc2a31..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2017
- * Texas Instruments, <www.ti.com>
- *
- * Franklin S Cooper Jr. <fcooper@ti.com>
- */
-
-#include <boot_fit.h>
-#include <common.h>
-#include <errno.h>
-#include <image.h>
-#include <log.h>
-#include <linux/libfdt.h>
-
-static int fdt_offset(const void *fit)
-{
-       int images, node, fdt_len, fdt_node, fdt_offset;
-       const char *fdt_name;
-
-       node = fit_find_config_node(fit);
-       if (node < 0)
-               return node;
-
-       images = fdt_path_offset(fit, FIT_IMAGES_PATH);
-       if (images < 0) {
-               debug("%s: Cannot find /images node: %d\n", __func__, images);
-               return -EINVAL;
-       }
-
-       fdt_name = fdt_getprop(fit, node, FIT_FDT_PROP, &fdt_len);
-       if (!fdt_name) {
-               debug("%s: Cannot find fdt name property: %d\n",
-                     __func__, fdt_len);
-               return -EINVAL;
-       }
-
-       fdt_node = fdt_subnode_offset(fit, images, fdt_name);
-       if (fdt_node < 0) {
-               debug("%s: Cannot find fdt node '%s': %d\n",
-                     __func__, fdt_name, fdt_node);
-               return -EINVAL;
-       }
-
-       fdt_offset = fdt_getprop_u32(fit, fdt_node, "data-offset");
-
-       if (fdt_offset == FDT_ERROR)
-               return -ENOENT;
-
-       fdt_len = fdt_getprop_u32(fit, fdt_node, "data-size");
-
-       if (fdt_len < 0)
-               return fdt_len;
-
-       return fdt_offset;
-}
-
-void *locate_dtb_in_fit(const void *fit)
-{
-       struct image_header *header;
-       int size;
-       int ret;
-
-       size = fdt_totalsize(fit);
-       size = (size + 3) & ~3;
-
-       header = (struct image_header *)fit;
-
-       if (image_get_magic(header) != FDT_MAGIC) {
-               debug("No FIT image appended to U-boot\n");
-               return NULL;
-       }
-
-       ret = fdt_offset(fit);
-
-       if (ret < 0)
-               return NULL;
-       else
-               return (void *)fit+size+ret;
-}
diff --git a/common/bootm.c b/common/bootm.c
deleted file mode 100644 (file)
index 4482f84..0000000
+++ /dev/null
@@ -1,1038 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2000-2009
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#ifndef USE_HOSTCC
-#include <common.h>
-#include <bootstage.h>
-#include <cli.h>
-#include <cpu_func.h>
-#include <env.h>
-#include <errno.h>
-#include <fdt_support.h>
-#include <irq_func.h>
-#include <lmb.h>
-#include <log.h>
-#include <malloc.h>
-#include <mapmem.h>
-#include <net.h>
-#include <asm/cache.h>
-#include <asm/global_data.h>
-#include <asm/io.h>
-#include <linux/sizes.h>
-#if defined(CONFIG_CMD_USB)
-#include <usb.h>
-#endif
-#else
-#include "mkimage.h"
-#endif
-
-#include <command.h>
-#include <bootm.h>
-#include <image.h>
-
-#ifndef CONFIG_SYS_BOOTM_LEN
-/* use 8MByte as default max gunzip size */
-#define CONFIG_SYS_BOOTM_LEN   0x800000
-#endif
-
-#define MAX_CMDLINE_SIZE       SZ_4K
-
-#define IH_INITRD_ARCH IH_ARCH_DEFAULT
-
-#ifndef USE_HOSTCC
-
-DECLARE_GLOBAL_DATA_PTR;
-
-bootm_headers_t images;                /* pointers to os/initrd/fdt images */
-
-static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
-                                  char *const argv[], bootm_headers_t *images,
-                                  ulong *os_data, ulong *os_len);
-
-__weak void board_quiesce_devices(void)
-{
-}
-
-#ifdef CONFIG_LMB
-static void boot_start_lmb(bootm_headers_t *images)
-{
-       ulong           mem_start;
-       phys_size_t     mem_size;
-
-       mem_start = env_get_bootm_low();
-       mem_size = env_get_bootm_size();
-
-       lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
-                                  mem_size, NULL);
-}
-#else
-#define lmb_reserve(lmb, base, size)
-static inline void boot_start_lmb(bootm_headers_t *images) { }
-#endif
-
-static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc,
-                      char *const argv[])
-{
-       memset((void *)&images, 0, sizeof(images));
-       images.verify = env_get_yesno("verify");
-
-       boot_start_lmb(&images);
-
-       bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
-       images.state = BOOTM_STATE_START;
-
-       return 0;
-}
-
-static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
-                        char *const argv[])
-{
-       const void *os_hdr;
-       bool ep_found = false;
-       int ret;
-
-       /* get kernel image header, start address and length */
-       os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
-                       &images, &images.os.image_start, &images.os.image_len);
-       if (images.os.image_len == 0) {
-               puts("ERROR: can't get kernel image!\n");
-               return 1;
-       }
-
-       /* get image parameters */
-       switch (genimg_get_format(os_hdr)) {
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
-       case IMAGE_FORMAT_LEGACY:
-               images.os.type = image_get_type(os_hdr);
-               images.os.comp = image_get_comp(os_hdr);
-               images.os.os = image_get_os(os_hdr);
-
-               images.os.end = image_get_image_end(os_hdr);
-               images.os.load = image_get_load(os_hdr);
-               images.os.arch = image_get_arch(os_hdr);
-               break;
-#endif
-#if CONFIG_IS_ENABLED(FIT)
-       case IMAGE_FORMAT_FIT:
-               if (fit_image_get_type(images.fit_hdr_os,
-                                      images.fit_noffset_os,
-                                      &images.os.type)) {
-                       puts("Can't get image type!\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
-                       return 1;
-               }
-
-               if (fit_image_get_comp(images.fit_hdr_os,
-                                      images.fit_noffset_os,
-                                      &images.os.comp)) {
-                       puts("Can't get image compression!\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
-                       return 1;
-               }
-
-               if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
-                                    &images.os.os)) {
-                       puts("Can't get image OS!\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_OS);
-                       return 1;
-               }
-
-               if (fit_image_get_arch(images.fit_hdr_os,
-                                      images.fit_noffset_os,
-                                      &images.os.arch)) {
-                       puts("Can't get image ARCH!\n");
-                       return 1;
-               }
-
-               images.os.end = fit_get_end(images.fit_hdr_os);
-
-               if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
-                                      &images.os.load)) {
-                       puts("Can't get image load address!\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
-                       return 1;
-               }
-               break;
-#endif
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
-       case IMAGE_FORMAT_ANDROID:
-               images.os.type = IH_TYPE_KERNEL;
-               images.os.comp = android_image_get_kcomp(os_hdr);
-               images.os.os = IH_OS_LINUX;
-
-               images.os.end = android_image_get_end(os_hdr);
-               images.os.load = android_image_get_kload(os_hdr);
-               images.ep = images.os.load;
-               ep_found = true;
-               break;
-#endif
-       default:
-               puts("ERROR: unknown image format type!\n");
-               return 1;
-       }
-
-       /* If we have a valid setup.bin, we will use that for entry (x86) */
-       if (images.os.arch == IH_ARCH_I386 ||
-           images.os.arch == IH_ARCH_X86_64) {
-               ulong len;
-
-               ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
-               if (ret < 0 && ret != -ENOENT) {
-                       puts("Could not find a valid setup.bin for x86\n");
-                       return 1;
-               }
-               /* Kernel entry point is the setup.bin */
-       } else if (images.legacy_hdr_valid) {
-               images.ep = image_get_ep(&images.legacy_hdr_os_copy);
-#if CONFIG_IS_ENABLED(FIT)
-       } else if (images.fit_uname_os) {
-               int ret;
-
-               ret = fit_image_get_entry(images.fit_hdr_os,
-                                         images.fit_noffset_os, &images.ep);
-               if (ret) {
-                       puts("Can't get entry point property!\n");
-                       return 1;
-               }
-#endif
-       } else if (!ep_found) {
-               puts("Could not find kernel entry point!\n");
-               return 1;
-       }
-
-       if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
-               if (CONFIG_IS_ENABLED(CMD_BOOTI) &&
-                   images.os.arch == IH_ARCH_ARM64) {
-                       ulong image_addr;
-                       ulong image_size;
-
-                       ret = booti_setup(images.os.image_start, &image_addr,
-                                         &image_size, true);
-                       if (ret != 0)
-                               return 1;
-
-                       images.os.type = IH_TYPE_KERNEL;
-                       images.os.load = image_addr;
-                       images.ep = image_addr;
-               } else {
-                       images.os.load = images.os.image_start;
-                       images.ep += images.os.image_start;
-               }
-       }
-
-       images.os.start = map_to_sysmem(os_hdr);
-
-       return 0;
-}
-
-/**
- * bootm_find_images - wrapper to find and locate various images
- * @flag: Ignored Argument
- * @argc: command argument count
- * @argv: command argument list
- * @start: OS image start address
- * @size: OS image size
- *
- * boot_find_images() will attempt to load an available ramdisk,
- * flattened device tree, as well as specifically marked
- * "loadable" images (loadables are FIT only)
- *
- * Note: bootm_find_images will skip an image if it is not found
- *
- * @return:
- *     0, if all existing images were loaded correctly
- *     1, if an image is found but corrupted, or invalid
- */
-int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
-                     ulong size)
-{
-       int ret;
-
-       /* find ramdisk */
-       ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
-                              &images.rd_start, &images.rd_end);
-       if (ret) {
-               puts("Ramdisk image is corrupt or invalid\n");
-               return 1;
-       }
-
-       /* check if ramdisk overlaps OS image */
-       if (images.rd_start && (((ulong)images.rd_start >= start &&
-                                (ulong)images.rd_start < start + size) ||
-                               ((ulong)images.rd_end > start &&
-                                (ulong)images.rd_end <= start + size) ||
-                               ((ulong)images.rd_start < start &&
-                                (ulong)images.rd_end >= start + size))) {
-               printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n",
-                      start, start + size);
-               return 1;
-       }
-
-#if CONFIG_IS_ENABLED(OF_LIBFDT)
-       /* find flattened device tree */
-       ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
-                          &images.ft_addr, &images.ft_len);
-       if (ret) {
-               puts("Could not find a valid device tree\n");
-               return 1;
-       }
-
-       /* check if FDT overlaps OS image */
-       if (images.ft_addr &&
-           (((ulong)images.ft_addr >= start &&
-             (ulong)images.ft_addr <= start + size) ||
-            ((ulong)images.ft_addr + images.ft_len >= start &&
-             (ulong)images.ft_addr + images.ft_len <= start + size))) {
-               printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n",
-                      start, start + size);
-               return 1;
-       }
-
-       if (CONFIG_IS_ENABLED(CMD_FDT))
-               set_working_fdt_addr(map_to_sysmem(images.ft_addr));
-#endif
-
-#if CONFIG_IS_ENABLED(FIT)
-       if (IS_ENABLED(CONFIG_FPGA)) {
-               /* find bitstreams */
-               ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
-                                   NULL, NULL);
-               if (ret) {
-                       printf("FPGA image is corrupted or invalid\n");
-                       return 1;
-               }
-       }
-
-       /* find all of the loadables */
-       ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
-                              NULL, NULL);
-       if (ret) {
-               printf("Loadable(s) is corrupt or invalid\n");
-               return 1;
-       }
-#endif
-
-       return 0;
-}
-
-static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc,
-                           char *const argv[])
-{
-       if (((images.os.type == IH_TYPE_KERNEL) ||
-            (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
-            (images.os.type == IH_TYPE_MULTI)) &&
-           (images.os.os == IH_OS_LINUX ||
-                images.os.os == IH_OS_VXWORKS))
-               return bootm_find_images(flag, argc, argv, 0, 0);
-
-       return 0;
-}
-#endif /* USE_HOSTC */
-
-#if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE)
-/**
- * handle_decomp_error() - display a decompression error
- *
- * This function tries to produce a useful message. In the case where the
- * uncompressed size is the same as the available space, we can assume that
- * the image is too large for the buffer.
- *
- * @comp_type:         Compression type being used (IH_COMP_...)
- * @uncomp_size:       Number of bytes uncompressed
- * @ret:               errno error code received from compression library
- * @return Appropriate BOOTM_ERR_ error code
- */
-static int handle_decomp_error(int comp_type, size_t uncomp_size, int ret)
-{
-       const char *name = genimg_get_comp_name(comp_type);
-
-       /* ENOSYS means unimplemented compression type, don't reset. */
-       if (ret == -ENOSYS)
-               return BOOTM_ERR_UNIMPLEMENTED;
-
-       if (uncomp_size >= CONFIG_SYS_BOOTM_LEN)
-               printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
-       else
-               printf("%s: uncompress error %d\n", name, ret);
-
-       /*
-        * The decompression routines are now safe, so will not write beyond
-        * their bounds. Probably it is not necessary to reset, but maintain
-        * the current behaviour for now.
-        */
-       printf("Must RESET board to recover\n");
-#ifndef USE_HOSTCC
-       bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
-#endif
-
-       return BOOTM_ERR_RESET;
-}
-#endif
-
-#ifndef USE_HOSTCC
-static int bootm_load_os(bootm_headers_t *images, int boot_progress)
-{
-       image_info_t os = images->os;
-       ulong load = os.load;
-       ulong load_end;
-       ulong blob_start = os.start;
-       ulong blob_end = os.end;
-       ulong image_start = os.image_start;
-       ulong image_len = os.image_len;
-       ulong flush_start = ALIGN_DOWN(load, ARCH_DMA_MINALIGN);
-       bool no_overlap;
-       void *load_buf, *image_buf;
-       int err;
-
-       load_buf = map_sysmem(load, 0);
-       image_buf = map_sysmem(os.image_start, image_len);
-       err = image_decomp(os.comp, load, os.image_start, os.type,
-                          load_buf, image_buf, image_len,
-                          CONFIG_SYS_BOOTM_LEN, &load_end);
-       if (err) {
-               err = handle_decomp_error(os.comp, load_end - load, err);
-               bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
-               return err;
-       }
-       /* We need the decompressed image size in the next steps */
-       images->os.image_len = load_end - load;
-
-       flush_cache(flush_start, ALIGN(load_end, ARCH_DMA_MINALIGN) - flush_start);
-
-       debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end);
-       bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
-
-       no_overlap = (os.comp == IH_COMP_NONE && load == image_start);
-
-       if (!no_overlap && load < blob_end && load_end > blob_start) {
-               debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
-                     blob_start, blob_end);
-               debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
-                     load_end);
-
-               /* Check what type of image this is. */
-               if (images->legacy_hdr_valid) {
-                       if (image_get_type(&images->legacy_hdr_os_copy)
-                                       == IH_TYPE_MULTI)
-                               puts("WARNING: legacy format multi component image overwritten\n");
-                       return BOOTM_ERR_OVERLAP;
-               } else {
-                       puts("ERROR: new format image overwritten - must RESET the board to recover\n");
-                       bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
-                       return BOOTM_ERR_RESET;
-               }
-       }
-
-       lmb_reserve(&images->lmb, images->os.load, (load_end -
-                                                   images->os.load));
-       return 0;
-}
-
-/**
- * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
- *
- * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
- *     enabled)
- */
-ulong bootm_disable_interrupts(void)
-{
-       ulong iflag;
-
-       /*
-        * We have reached the point of no return: we are going to
-        * overwrite all exception vector code, so we cannot easily
-        * recover from any failures any more...
-        */
-       iflag = disable_interrupts();
-#ifdef CONFIG_NETCONSOLE
-       /* Stop the ethernet stack if NetConsole could have left it up */
-       eth_halt();
-# ifndef CONFIG_DM_ETH
-       eth_unregister(eth_get_dev());
-# endif
-#endif
-
-#if defined(CONFIG_CMD_USB)
-       /*
-        * turn off USB to prevent the host controller from writing to the
-        * SDRAM while Linux is booting. This could happen (at least for OHCI
-        * controller), because the HCCA (Host Controller Communication Area)
-        * lies within the SDRAM and the host controller writes continously to
-        * this area (as busmaster!). The HccaFrameNumber is for example
-        * updated every 1 ms within the HCCA structure in SDRAM! For more
-        * details see the OpenHCI specification.
-        */
-       usb_stop();
-#endif
-       return iflag;
-}
-
-#define CONSOLE_ARG            "console="
-#define CONSOLE_ARG_SIZE       sizeof(CONSOLE_ARG)
-
-/**
- * fixup_silent_linux() - Handle silencing the linux boot if required
- *
- * This uses the silent_linux envvar to control whether to add/set a "console="
- * parameter to the command line
- *
- * @buf: Buffer containing the string to process
- * @maxlen: Maximum length of buffer
- * @return 0 if OK, -ENOSPC if @maxlen is too small
- */
-static int fixup_silent_linux(char *buf, int maxlen)
-{
-       int want_silent;
-       char *cmdline;
-       int size;
-
-       /*
-        * Move the input string to the end of buffer. The output string will be
-        * built up at the start.
-        */
-       size = strlen(buf) + 1;
-       if (size * 2 > maxlen)
-               return -ENOSPC;
-       cmdline = buf + maxlen - size;
-       memmove(cmdline, buf, size);
-       /*
-        * Only fix cmdline when requested. The environment variable can be:
-        *
-        *      no - we never fixup
-        *      yes - we always fixup
-        *      unset - we rely on the console silent flag
-        */
-       want_silent = env_get_yesno("silent_linux");
-       if (want_silent == 0)
-               return 0;
-       else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
-               return 0;
-
-       debug("before silent fix-up: %s\n", cmdline);
-       if (*cmdline) {
-               char *start = strstr(cmdline, CONSOLE_ARG);
-
-               /* Check space for maximum possible new command line */
-               if (size + CONSOLE_ARG_SIZE > maxlen)
-                       return -ENOSPC;
-
-               if (start) {
-                       char *end = strchr(start, ' ');
-                       int start_bytes;
-
-                       start_bytes = start - cmdline + CONSOLE_ARG_SIZE - 1;
-                       strncpy(buf, cmdline, start_bytes);
-                       if (end)
-                               strcpy(buf + start_bytes, end);
-                       else
-                               buf[start_bytes] = '\0';
-               } else {
-                       sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
-               }
-               if (buf + strlen(buf) >= cmdline)
-                       return -ENOSPC;
-       } else {
-               if (maxlen < sizeof(CONSOLE_ARG))
-                       return -ENOSPC;
-               strcpy(buf, CONSOLE_ARG);
-       }
-       debug("after silent fix-up: %s\n", buf);
-
-       return 0;
-}
-
-/**
- * process_subst() - Handle substitution of ${...} fields in the environment
- *
- * Handle variable substitution in the provided buffer
- *
- * @buf: Buffer containing the string to process
- * @maxlen: Maximum length of buffer
- * @return 0 if OK, -ENOSPC if @maxlen is too small
- */
-static int process_subst(char *buf, int maxlen)
-{
-       char *cmdline;
-       int size;
-       int ret;
-
-       /* Move to end of buffer */
-       size = strlen(buf) + 1;
-       cmdline = buf + maxlen - size;
-       if (buf + size > cmdline)
-               return -ENOSPC;
-       memmove(cmdline, buf, size);
-
-       ret = cli_simple_process_macros(cmdline, buf, cmdline - buf);
-
-       return ret;
-}
-
-int bootm_process_cmdline(char *buf, int maxlen, int flags)
-{
-       int ret;
-
-       /* Check config first to enable compiler to eliminate code */
-       if (IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
-           !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) &&
-           (flags & BOOTM_CL_SILENT)) {
-               ret = fixup_silent_linux(buf, maxlen);
-               if (ret)
-                       return log_msg_ret("silent", ret);
-       }
-       if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && IS_ENABLED(CONFIG_CMDLINE) &&
-           (flags & BOOTM_CL_SUBST)) {
-               ret = process_subst(buf, maxlen);
-               if (ret)
-                       return log_msg_ret("subst", ret);
-       }
-
-       return 0;
-}
-
-int bootm_process_cmdline_env(int flags)
-{
-       const int maxlen = MAX_CMDLINE_SIZE;
-       bool do_silent;
-       const char *env;
-       char *buf;
-       int ret;
-
-       /* First check if any action is needed */
-       do_silent = IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
-           !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) && (flags & BOOTM_CL_SILENT);
-       if (!do_silent && !IS_ENABLED(CONFIG_BOOTARGS_SUBST))
-               return 0;
-
-       env = env_get("bootargs");
-       if (env && strlen(env) >= maxlen)
-               return -E2BIG;
-       buf = malloc(maxlen);
-       if (!buf)
-               return -ENOMEM;
-       if (env)
-               strcpy(buf, env);
-       else
-               *buf = '\0';
-       ret = bootm_process_cmdline(buf, maxlen, flags);
-       if (!ret) {
-               ret = env_set("bootargs", buf);
-
-               /*
-                * If buf is "" and bootargs does not exist, this will produce
-                * an error trying to delete bootargs. Ignore it
-                */
-               if (ret == -ENOENT)
-                       ret = 0;
-       }
-       free(buf);
-       if (ret)
-               return log_msg_ret("env", ret);
-
-       return 0;
-}
-
-/**
- * Execute selected states of the bootm command.
- *
- * Note the arguments to this state must be the first argument, Any 'bootm'
- * or sub-command arguments must have already been taken.
- *
- * Note that if states contains more than one flag it MUST contain
- * BOOTM_STATE_START, since this handles and consumes the command line args.
- *
- * Also note that aside from boot_os_fn functions and bootm_load_os no other
- * functions we store the return value of in 'ret' may use a negative return
- * value, without special handling.
- *
- * @param cmdtp                Pointer to bootm command table entry
- * @param flag         Command flags (CMD_FLAG_...)
- * @param argc         Number of subcommand arguments (0 = no arguments)
- * @param argv         Arguments
- * @param states       Mask containing states to run (BOOTM_STATE_...)
- * @param images       Image header information
- * @param boot_progress 1 to show boot progress, 0 to not do this
- * @return 0 if ok, something else on error. Some errors will cause this
- *     function to perform a reboot! If states contains BOOTM_STATE_OS_GO
- *     then the intent is to boot an OS, so this function will not return
- *     unless the image type is standalone.
- */
-int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
-                   char *const argv[], int states, bootm_headers_t *images,
-                   int boot_progress)
-{
-       boot_os_fn *boot_fn;
-       ulong iflag = 0;
-       int ret = 0, need_boot_fn;
-
-       images->state |= states;
-
-       /*
-        * Work through the states and see how far we get. We stop on
-        * any error.
-        */
-       if (states & BOOTM_STATE_START)
-               ret = bootm_start(cmdtp, flag, argc, argv);
-
-       if (!ret && (states & BOOTM_STATE_FINDOS))
-               ret = bootm_find_os(cmdtp, flag, argc, argv);
-
-       if (!ret && (states & BOOTM_STATE_FINDOTHER))
-               ret = bootm_find_other(cmdtp, flag, argc, argv);
-
-       /* Load the OS */
-       if (!ret && (states & BOOTM_STATE_LOADOS)) {
-               iflag = bootm_disable_interrupts();
-               ret = bootm_load_os(images, 0);
-               if (ret && ret != BOOTM_ERR_OVERLAP)
-                       goto err;
-               else if (ret == BOOTM_ERR_OVERLAP)
-                       ret = 0;
-       }
-
-       /* Relocate the ramdisk */
-#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
-       if (!ret && (states & BOOTM_STATE_RAMDISK)) {
-               ulong rd_len = images->rd_end - images->rd_start;
-
-               ret = boot_ramdisk_high(&images->lmb, images->rd_start,
-                       rd_len, &images->initrd_start, &images->initrd_end);
-               if (!ret) {
-                       env_set_hex("initrd_start", images->initrd_start);
-                       env_set_hex("initrd_end", images->initrd_end);
-               }
-       }
-#endif
-#if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB)
-       if (!ret && (states & BOOTM_STATE_FDT)) {
-               boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
-               ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
-                                       &images->ft_len);
-       }
-#endif
-
-       /* From now on, we need the OS boot function */
-       if (ret)
-               return ret;
-       boot_fn = bootm_os_get_boot_func(images->os.os);
-       need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
-                       BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
-                       BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
-       if (boot_fn == NULL && need_boot_fn) {
-               if (iflag)
-                       enable_interrupts();
-               printf("ERROR: booting os '%s' (%d) is not supported\n",
-                      genimg_get_os_name(images->os.os), images->os.os);
-               bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
-               return 1;
-       }
-
-
-       /* Call various other states that are not generally used */
-       if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
-               ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
-       if (!ret && (states & BOOTM_STATE_OS_BD_T))
-               ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
-       if (!ret && (states & BOOTM_STATE_OS_PREP)) {
-               ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX);
-               if (ret) {
-                       printf("Cmdline setup failed (err=%d)\n", ret);
-                       ret = CMD_RET_FAILURE;
-                       goto err;
-               }
-               ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
-       }
-
-#ifdef CONFIG_TRACE
-       /* Pretend to run the OS, then run a user command */
-       if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
-               char *cmd_list = env_get("fakegocmd");
-
-               ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
-                               images, boot_fn);
-               if (!ret && cmd_list)
-                       ret = run_command_list(cmd_list, -1, flag);
-       }
-#endif
-
-       /* Check for unsupported subcommand. */
-       if (ret) {
-               puts("subcommand not supported\n");
-               return ret;
-       }
-
-       /* Now run the OS! We hope this doesn't return */
-       if (!ret && (states & BOOTM_STATE_OS_GO))
-               ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
-                               images, boot_fn);
-
-       /* Deal with any fallout */
-err:
-       if (iflag)
-               enable_interrupts();
-
-       if (ret == BOOTM_ERR_UNIMPLEMENTED)
-               bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
-       else if (ret == BOOTM_ERR_RESET)
-               do_reset(cmdtp, flag, argc, argv);
-
-       return ret;
-}
-
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
-/**
- * image_get_kernel - verify legacy format kernel image
- * @img_addr: in RAM address of the legacy format image to be verified
- * @verify: data CRC verification flag
- *
- * image_get_kernel() verifies legacy image integrity and returns pointer to
- * legacy image header if image verification was completed successfully.
- *
- * returns:
- *     pointer to a legacy image header if valid image was found
- *     otherwise return NULL
- */
-static image_header_t *image_get_kernel(ulong img_addr, int verify)
-{
-       image_header_t *hdr = (image_header_t *)img_addr;
-
-       if (!image_check_magic(hdr)) {
-               puts("Bad Magic Number\n");
-               bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
-               return NULL;
-       }
-       bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
-
-       if (!image_check_hcrc(hdr)) {
-               puts("Bad Header Checksum\n");
-               bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
-               return NULL;
-       }
-
-       bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
-       image_print_contents(hdr);
-
-       if (verify) {
-               puts("   Verifying Checksum ... ");
-               if (!image_check_dcrc(hdr)) {
-                       printf("Bad Data CRC\n");
-                       bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
-                       return NULL;
-               }
-               puts("OK\n");
-       }
-       bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
-
-       if (!image_check_target_arch(hdr)) {
-               printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
-               bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
-               return NULL;
-       }
-       return hdr;
-}
-#endif
-
-/**
- * boot_get_kernel - find kernel image
- * @os_data: pointer to a ulong variable, will hold os data start address
- * @os_len: pointer to a ulong variable, will hold os data length
- *
- * boot_get_kernel() tries to find a kernel image, verifies its integrity
- * and locates kernel data.
- *
- * returns:
- *     pointer to image header if valid image was found, plus kernel start
- *     address and length, otherwise NULL
- */
-static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
-                                  char *const argv[], bootm_headers_t *images,
-                                  ulong *os_data, ulong *os_len)
-{
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
-       image_header_t  *hdr;
-#endif
-       ulong           img_addr;
-       const void *buf;
-       const char      *fit_uname_config = NULL;
-       const char      *fit_uname_kernel = NULL;
-#if CONFIG_IS_ENABLED(FIT)
-       int             os_noffset;
-#endif
-
-       img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
-                                             &fit_uname_config,
-                                             &fit_uname_kernel);
-
-       bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
-
-       /* check image type, for FIT images get FIT kernel node */
-       *os_data = *os_len = 0;
-       buf = map_sysmem(img_addr, 0);
-       switch (genimg_get_format(buf)) {
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
-       case IMAGE_FORMAT_LEGACY:
-               printf("## Booting kernel from Legacy Image at %08lx ...\n",
-                      img_addr);
-               hdr = image_get_kernel(img_addr, images->verify);
-               if (!hdr)
-                       return NULL;
-               bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
-
-               /* get os_data and os_len */
-               switch (image_get_type(hdr)) {
-               case IH_TYPE_KERNEL:
-               case IH_TYPE_KERNEL_NOLOAD:
-                       *os_data = image_get_data(hdr);
-                       *os_len = image_get_data_size(hdr);
-                       break;
-               case IH_TYPE_MULTI:
-                       image_multi_getimg(hdr, 0, os_data, os_len);
-                       break;
-               case IH_TYPE_STANDALONE:
-                       *os_data = image_get_data(hdr);
-                       *os_len = image_get_data_size(hdr);
-                       break;
-               default:
-                       printf("Wrong Image Type for %s command\n",
-                              cmdtp->name);
-                       bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
-                       return NULL;
-               }
-
-               /*
-                * copy image header to allow for image overwrites during
-                * kernel decompression.
-                */
-               memmove(&images->legacy_hdr_os_copy, hdr,
-                       sizeof(image_header_t));
-
-               /* save pointer to image header */
-               images->legacy_hdr_os = hdr;
-
-               images->legacy_hdr_valid = 1;
-               bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
-               break;
-#endif
-#if CONFIG_IS_ENABLED(FIT)
-       case IMAGE_FORMAT_FIT:
-               os_noffset = fit_image_load(images, img_addr,
-                               &fit_uname_kernel, &fit_uname_config,
-                               IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
-                               BOOTSTAGE_ID_FIT_KERNEL_START,
-                               FIT_LOAD_IGNORED, os_data, os_len);
-               if (os_noffset < 0)
-                       return NULL;
-
-               images->fit_hdr_os = map_sysmem(img_addr, 0);
-               images->fit_uname_os = fit_uname_kernel;
-               images->fit_uname_cfg = fit_uname_config;
-               images->fit_noffset_os = os_noffset;
-               break;
-#endif
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
-       case IMAGE_FORMAT_ANDROID:
-               printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
-               if (android_image_get_kernel(buf, images->verify,
-                                            os_data, os_len))
-                       return NULL;
-               break;
-#endif
-       default:
-               printf("Wrong Image Format for %s command\n", cmdtp->name);
-               bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
-               return NULL;
-       }
-
-       debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
-             *os_data, *os_len, *os_len);
-
-       return buf;
-}
-
-/**
- * switch_to_non_secure_mode() - switch to non-secure mode
- *
- * This routine is overridden by architectures requiring this feature.
- */
-void __weak switch_to_non_secure_mode(void)
-{
-}
-
-#else /* USE_HOSTCC */
-
-#if defined(CONFIG_FIT_SIGNATURE)
-static int bootm_host_load_image(const void *fit, int req_image_type,
-                                int cfg_noffset)
-{
-       const char *fit_uname_config = NULL;
-       ulong data, len;
-       bootm_headers_t images;
-       int noffset;
-       ulong load_end;
-       uint8_t image_type;
-       uint8_t imape_comp;
-       void *load_buf;
-       int ret;
-
-       fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
-       memset(&images, '\0', sizeof(images));
-       images.verify = 1;
-       noffset = fit_image_load(&images, (ulong)fit,
-               NULL, &fit_uname_config,
-               IH_ARCH_DEFAULT, req_image_type, -1,
-               FIT_LOAD_IGNORED, &data, &len);
-       if (noffset < 0)
-               return noffset;
-       if (fit_image_get_type(fit, noffset, &image_type)) {
-               puts("Can't get image type!\n");
-               return -EINVAL;
-       }
-
-       if (fit_image_get_comp(fit, noffset, &imape_comp)) {
-               puts("Can't get image compression!\n");
-               return -EINVAL;
-       }
-
-       /* Allow the image to expand by a factor of 4, should be safe */
-       load_buf = malloc((1 << 20) + len * 4);
-       ret = image_decomp(imape_comp, 0, data, image_type, load_buf,
-                          (void *)data, len, CONFIG_SYS_BOOTM_LEN,
-                          &load_end);
-       free(load_buf);
-
-       if (ret) {
-               ret = handle_decomp_error(imape_comp, load_end - 0, ret);
-               if (ret != BOOTM_ERR_UNIMPLEMENTED)
-                       return ret;
-       }
-
-       return 0;
-}
-
-int bootm_host_load_images(const void *fit, int cfg_noffset)
-{
-       static uint8_t image_types[] = {
-               IH_TYPE_KERNEL,
-               IH_TYPE_FLATDT,
-               IH_TYPE_RAMDISK,
-       };
-       int err = 0;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(image_types); i++) {
-               int ret;
-
-               ret = bootm_host_load_image(fit, image_types[i], cfg_noffset);
-               if (!err && ret && ret != -ENOENT)
-                       err = ret;
-       }
-
-       /* Return the first error we found */
-       return err;
-}
-#endif
-
-#endif /* ndef USE_HOSTCC */
diff --git a/common/bootm_os.c b/common/bootm_os.c
deleted file mode 100644 (file)
index 39623f9..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2000-2009
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#include <common.h>
-#include <bootm.h>
-#include <bootstage.h>
-#include <cpu_func.h>
-#include <efi_loader.h>
-#include <env.h>
-#include <fdt_support.h>
-#include <image.h>
-#include <lmb.h>
-#include <log.h>
-#include <asm/global_data.h>
-#include <linux/libfdt.h>
-#include <malloc.h>
-#include <mapmem.h>
-#include <vxworks.h>
-#include <tee/optee.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static int do_bootm_standalone(int flag, int argc, char *const argv[],
-                              bootm_headers_t *images)
-{
-       char *s;
-       int (*appl)(int, char *const[]);
-
-       /* Don't start if "autostart" is set to "no" */
-       s = env_get("autostart");
-       if ((s != NULL) && !strcmp(s, "no")) {
-               env_set_hex("filesize", images->os.image_len);
-               return 0;
-       }
-       appl = (int (*)(int, char * const []))images->ep;
-       appl(argc, argv);
-       return 0;
-}
-
-/*******************************************************************/
-/* OS booting routines */
-/*******************************************************************/
-
-#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
-static void copy_args(char *dest, int argc, char *const argv[], char delim)
-{
-       int i;
-
-       for (i = 0; i < argc; i++) {
-               if (i > 0)
-                       *dest++ = delim;
-               strcpy(dest, argv[i]);
-               dest += strlen(argv[i]);
-       }
-}
-#endif
-
-static void __maybe_unused fit_unsupported_reset(const char *msg)
-{
-       if (CONFIG_IS_ENABLED(FIT_VERBOSE)) {
-               printf("! FIT images not supported for '%s' - must reset board to recover!\n",
-                      msg);
-       }
-}
-
-#ifdef CONFIG_BOOTM_NETBSD
-static int do_bootm_netbsd(int flag, int argc, char *const argv[],
-                          bootm_headers_t *images)
-{
-       void (*loader)(struct bd_info *, image_header_t *, char *, char *);
-       image_header_t *os_hdr, *hdr;
-       ulong kernel_data, kernel_len;
-       char *cmdline;
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("NetBSD");
-               return 1;
-       }
-#endif
-       hdr = images->legacy_hdr_os;
-
-       /*
-        * Booting a (NetBSD) kernel image
-        *
-        * This process is pretty similar to a standalone application:
-        * The (first part of an multi-) image must be a stage-2 loader,
-        * which in turn is responsible for loading & invoking the actual
-        * kernel.  The only differences are the parameters being passed:
-        * besides the board info strucure, the loader expects a command
-        * line, the name of the console device, and (optionally) the
-        * address of the original image header.
-        */
-       os_hdr = NULL;
-       if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
-               image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
-               if (kernel_len)
-                       os_hdr = hdr;
-       }
-
-       if (argc > 0) {
-               ulong len;
-               int   i;
-
-               for (i = 0, len = 0; i < argc; i += 1)
-                       len += strlen(argv[i]) + 1;
-               cmdline = malloc(len);
-               copy_args(cmdline, argc, argv, ' ');
-       } else {
-               cmdline = env_get("bootargs");
-               if (cmdline == NULL)
-                       cmdline = "";
-       }
-
-       loader = (void (*)(struct bd_info *, image_header_t *, char *, char *))images->ep;
-
-       printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
-              (ulong)loader);
-
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-       /*
-        * NetBSD Stage-2 Loader Parameters:
-        *   arg[0]: pointer to board info data
-        *   arg[1]: image load address
-        *   arg[2]: char pointer to the console device to use
-        *   arg[3]: char pointer to the boot arguments
-        */
-       (*loader)(gd->bd, os_hdr, "", cmdline);
-
-       return 1;
-}
-#endif /* CONFIG_BOOTM_NETBSD*/
-
-#ifdef CONFIG_LYNXKDI
-static int do_bootm_lynxkdi(int flag, int argc, char *const argv[],
-                           bootm_headers_t *images)
-{
-       image_header_t *hdr = &images->legacy_hdr_os_copy;
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("Lynx");
-               return 1;
-       }
-#endif
-
-       lynxkdi_boot((image_header_t *)hdr);
-
-       return 1;
-}
-#endif /* CONFIG_LYNXKDI */
-
-#ifdef CONFIG_BOOTM_RTEMS
-static int do_bootm_rtems(int flag, int argc, char *const argv[],
-                         bootm_headers_t *images)
-{
-       void (*entry_point)(struct bd_info *);
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("RTEMS");
-               return 1;
-       }
-#endif
-
-       entry_point = (void (*)(struct bd_info *))images->ep;
-
-       printf("## Transferring control to RTEMS (at address %08lx) ...\n",
-              (ulong)entry_point);
-
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-       /*
-        * RTEMS Parameters:
-        *   r3: ptr to board info data
-        */
-       (*entry_point)(gd->bd);
-
-       return 1;
-}
-#endif /* CONFIG_BOOTM_RTEMS */
-
-#if defined(CONFIG_BOOTM_OSE)
-static int do_bootm_ose(int flag, int argc, char *const argv[],
-                       bootm_headers_t *images)
-{
-       void (*entry_point)(void);
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("OSE");
-               return 1;
-       }
-#endif
-
-       entry_point = (void (*)(void))images->ep;
-
-       printf("## Transferring control to OSE (at address %08lx) ...\n",
-              (ulong)entry_point);
-
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-       /*
-        * OSE Parameters:
-        *   None
-        */
-       (*entry_point)();
-
-       return 1;
-}
-#endif /* CONFIG_BOOTM_OSE */
-
-#if defined(CONFIG_BOOTM_PLAN9)
-static int do_bootm_plan9(int flag, int argc, char *const argv[],
-                         bootm_headers_t *images)
-{
-       void (*entry_point)(void);
-       char *s;
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("Plan 9");
-               return 1;
-       }
-#endif
-
-       /* See README.plan9 */
-       s = env_get("confaddr");
-       if (s != NULL) {
-               char *confaddr = (char *)hextoul(s, NULL);
-
-               if (argc > 0) {
-                       copy_args(confaddr, argc, argv, '\n');
-               } else {
-                       s = env_get("bootargs");
-                       if (s != NULL)
-                               strcpy(confaddr, s);
-               }
-       }
-
-       entry_point = (void (*)(void))images->ep;
-
-       printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
-              (ulong)entry_point);
-
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-       /*
-        * Plan 9 Parameters:
-        *   None
-        */
-       (*entry_point)();
-
-       return 1;
-}
-#endif /* CONFIG_BOOTM_PLAN9 */
-
-#if defined(CONFIG_BOOTM_VXWORKS) && \
-       (defined(CONFIG_PPC) || defined(CONFIG_ARM))
-
-static void do_bootvx_fdt(bootm_headers_t *images)
-{
-#if defined(CONFIG_OF_LIBFDT)
-       int ret;
-       char *bootline;
-       ulong of_size = images->ft_len;
-       char **of_flat_tree = &images->ft_addr;
-       struct lmb *lmb = &images->lmb;
-
-       if (*of_flat_tree) {
-               boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
-
-               ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
-               if (ret)
-                       return;
-
-               /* Update ethernet nodes */
-               fdt_fixup_ethernet(*of_flat_tree);
-
-               ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
-               if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
-                       bootline = env_get("bootargs");
-                       if (bootline) {
-                               ret = fdt_find_and_setprop(*of_flat_tree,
-                                               "/chosen", "bootargs",
-                                               bootline,
-                                               strlen(bootline) + 1, 1);
-                               if (ret < 0) {
-                                       printf("## ERROR: %s : %s\n", __func__,
-                                              fdt_strerror(ret));
-                                       return;
-                               }
-                       }
-               } else {
-                       printf("## ERROR: %s : %s\n", __func__,
-                              fdt_strerror(ret));
-                       return;
-               }
-       }
-#endif
-
-       boot_prep_vxworks(images);
-
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-#if defined(CONFIG_OF_LIBFDT)
-       printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
-              (ulong)images->ep, (ulong)*of_flat_tree);
-#else
-       printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
-#endif
-
-       boot_jump_vxworks(images);
-
-       puts("## vxWorks terminated\n");
-}
-
-static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[],
-                                  bootm_headers_t *images)
-{
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("VxWorks");
-               return 1;
-       }
-#endif
-
-       do_bootvx_fdt(images);
-
-       return 1;
-}
-
-int do_bootm_vxworks(int flag, int argc, char *const argv[],
-                    bootm_headers_t *images)
-{
-       char *bootargs;
-       int pos;
-       unsigned long vxflags;
-       bool std_dtb = false;
-
-       /* get bootargs env */
-       bootargs = env_get("bootargs");
-
-       if (bootargs != NULL) {
-               for (pos = 0; pos < strlen(bootargs); pos++) {
-                       /* find f=0xnumber flag */
-                       if ((bootargs[pos] == '=') && (pos >= 1) &&
-                           (bootargs[pos - 1] == 'f')) {
-                               vxflags = hextoul(&bootargs[pos + 1], NULL);
-                               if (vxflags & VXWORKS_SYSFLG_STD_DTB)
-                                       std_dtb = true;
-                       }
-               }
-       }
-
-       if (std_dtb) {
-               if (flag & BOOTM_STATE_OS_PREP)
-                       printf("   Using standard DTB\n");
-               return do_bootm_linux(flag, argc, argv, images);
-       } else {
-               if (flag & BOOTM_STATE_OS_PREP)
-                       printf("   !!! WARNING !!! Using legacy DTB\n");
-               return do_bootm_vxworks_legacy(flag, argc, argv, images);
-       }
-}
-#endif
-
-#if defined(CONFIG_CMD_ELF)
-static int do_bootm_qnxelf(int flag, int argc, char *const argv[],
-                          bootm_headers_t *images)
-{
-       char *local_args[2];
-       char str[16];
-       int dcache;
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("QNX");
-               return 1;
-       }
-#endif
-
-       sprintf(str, "%lx", images->ep); /* write entry-point into string */
-       local_args[0] = argv[0];
-       local_args[1] = str;    /* and provide it via the arguments */
-
-       /*
-        * QNX images require the data cache is disabled.
-        */
-       dcache = dcache_status();
-       if (dcache)
-               dcache_disable();
-
-       do_bootelf(NULL, 0, 2, local_args);
-
-       if (dcache)
-               dcache_enable();
-
-       return 1;
-}
-#endif
-
-#ifdef CONFIG_INTEGRITY
-static int do_bootm_integrity(int flag, int argc, char *const argv[],
-                             bootm_headers_t *images)
-{
-       void (*entry_point)(void);
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-#if defined(CONFIG_FIT)
-       if (!images->legacy_hdr_valid) {
-               fit_unsupported_reset("INTEGRITY");
-               return 1;
-       }
-#endif
-
-       entry_point = (void (*)(void))images->ep;
-
-       printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
-              (ulong)entry_point);
-
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-       /*
-        * INTEGRITY Parameters:
-        *   None
-        */
-       (*entry_point)();
-
-       return 1;
-}
-#endif
-
-#ifdef CONFIG_BOOTM_OPENRTOS
-static int do_bootm_openrtos(int flag, int argc, char *const argv[],
-                            bootm_headers_t *images)
-{
-       void (*entry_point)(void);
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-       entry_point = (void (*)(void))images->ep;
-
-       printf("## Transferring control to OpenRTOS (at address %08lx) ...\n",
-               (ulong)entry_point);
-
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-       /*
-        * OpenRTOS Parameters:
-        *   None
-        */
-       (*entry_point)();
-
-       return 1;
-}
-#endif
-
-#ifdef CONFIG_BOOTM_OPTEE
-static int do_bootm_tee(int flag, int argc, char *const argv[],
-                       bootm_headers_t *images)
-{
-       int ret;
-
-       /* Verify OS type */
-       if (images->os.os != IH_OS_TEE) {
-               return 1;
-       };
-
-       /* Validate OPTEE header */
-       ret = optee_verify_bootm_image(images->os.image_start,
-                                      images->os.load,
-                                      images->os.image_len);
-       if (ret)
-               return ret;
-
-       /* Locate FDT etc */
-       ret = bootm_find_images(flag, argc, argv, 0, 0);
-       if (ret)
-               return ret;
-
-       /* From here we can run the regular linux boot path */
-       return do_bootm_linux(flag, argc, argv, images);
-}
-#endif
-
-#ifdef CONFIG_BOOTM_EFI
-static int do_bootm_efi(int flag, int argc, char *const argv[],
-                       bootm_headers_t *images)
-{
-       int ret;
-       efi_status_t efi_ret;
-       void *image_buf;
-
-       if (flag != BOOTM_STATE_OS_GO)
-               return 0;
-
-       /* Locate FDT, if provided */
-       ret = bootm_find_images(flag, argc, argv, 0, 0);
-       if (ret)
-               return ret;
-
-       /* Initialize EFI drivers */
-       efi_ret = efi_init_obj_list();
-       if (efi_ret != EFI_SUCCESS) {
-               printf("## Failed to initialize UEFI sub-system: r = %lu\n",
-                      efi_ret & ~EFI_ERROR_MASK);
-               return 1;
-       }
-
-       /* Install device tree */
-       efi_ret = efi_install_fdt(images->ft_len
-                                 ? images->ft_addr : EFI_FDT_USE_INTERNAL);
-       if (efi_ret != EFI_SUCCESS) {
-               printf("## Failed to install device tree: r = %lu\n",
-                      efi_ret & ~EFI_ERROR_MASK);
-               return 1;
-       }
-
-       /* Run EFI image */
-       printf("## Transferring control to EFI (at address %08lx) ...\n",
-              images->ep);
-       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
-
-       /* We expect to return */
-       images->os.type = IH_TYPE_STANDALONE;
-
-       image_buf = map_sysmem(images->ep, images->os.image_len);
-
-       efi_ret = efi_run_image(image_buf, images->os.image_len);
-       if (efi_ret != EFI_SUCCESS)
-               return 1;
-       return 0;
-}
-#endif
-
-static boot_os_fn *boot_os[] = {
-       [IH_OS_U_BOOT] = do_bootm_standalone,
-#ifdef CONFIG_BOOTM_LINUX
-       [IH_OS_LINUX] = do_bootm_linux,
-#endif
-#ifdef CONFIG_BOOTM_NETBSD
-       [IH_OS_NETBSD] = do_bootm_netbsd,
-#endif
-#ifdef CONFIG_LYNXKDI
-       [IH_OS_LYNXOS] = do_bootm_lynxkdi,
-#endif
-#ifdef CONFIG_BOOTM_RTEMS
-       [IH_OS_RTEMS] = do_bootm_rtems,
-#endif
-#if defined(CONFIG_BOOTM_OSE)
-       [IH_OS_OSE] = do_bootm_ose,
-#endif
-#if defined(CONFIG_BOOTM_PLAN9)
-       [IH_OS_PLAN9] = do_bootm_plan9,
-#endif
-#if defined(CONFIG_BOOTM_VXWORKS) && \
-       (defined(CONFIG_PPC) || defined(CONFIG_ARM) || defined(CONFIG_RISCV))
-       [IH_OS_VXWORKS] = do_bootm_vxworks,
-#endif
-#if defined(CONFIG_CMD_ELF)
-       [IH_OS_QNX] = do_bootm_qnxelf,
-#endif
-#ifdef CONFIG_INTEGRITY
-       [IH_OS_INTEGRITY] = do_bootm_integrity,
-#endif
-#ifdef CONFIG_BOOTM_OPENRTOS
-       [IH_OS_OPENRTOS] = do_bootm_openrtos,
-#endif
-#ifdef CONFIG_BOOTM_OPTEE
-       [IH_OS_TEE] = do_bootm_tee,
-#endif
-#ifdef CONFIG_BOOTM_EFI
-       [IH_OS_EFI] = do_bootm_efi,
-#endif
-};
-
-/* Allow for arch specific config before we boot */
-__weak void arch_preboot_os(void)
-{
-       /* please define platform specific arch_preboot_os() */
-}
-
-/* Allow for board specific config before we boot */
-__weak void board_preboot_os(void)
-{
-       /* please define board specific board_preboot_os() */
-}
-
-int boot_selected_os(int argc, char *const argv[], int state,
-                    bootm_headers_t *images, boot_os_fn *boot_fn)
-{
-       arch_preboot_os();
-       board_preboot_os();
-       boot_fn(state, argc, argv, images);
-
-       /* Stand-alone may return when 'autostart' is 'no' */
-       if (images->os.type == IH_TYPE_STANDALONE ||
-           IS_ENABLED(CONFIG_SANDBOX) ||
-           state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
-               return 0;
-       bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
-       debug("\n## Control returned to monitor - resetting...\n");
-
-       return BOOTM_ERR_RESET;
-}
-
-boot_os_fn *bootm_os_get_boot_func(int os)
-{
-#ifdef CONFIG_NEEDS_MANUAL_RELOC
-       static bool relocated;
-
-       if (!relocated) {
-               int i;
-
-               /* relocate boot function table */
-               for (i = 0; i < ARRAY_SIZE(boot_os); i++)
-                       if (boot_os[i] != NULL)
-                               boot_os[i] += gd->reloc_off;
-
-               relocated = true;
-       }
-#endif
-       return boot_os[os];
-}
diff --git a/common/bootretry.c b/common/bootretry.c
deleted file mode 100644 (file)
index dac891f..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2000
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#include <common.h>
-#include <bootretry.h>
-#include <cli.h>
-#include <env.h>
-#include <errno.h>
-#include <time.h>
-#include <watchdog.h>
-
-#ifndef CONFIG_BOOT_RETRY_MIN
-#define CONFIG_BOOT_RETRY_MIN CONFIG_BOOT_RETRY_TIME
-#endif
-
-static uint64_t endtime;  /* must be set, default is instant timeout */
-static int      retry_time = -1; /* -1 so can call readline before main_loop */
-
-/***************************************************************************
- * initialize command line timeout
- */
-void bootretry_init_cmd_timeout(void)
-{
-       char *s = env_get("bootretry");
-
-       if (s != NULL)
-               retry_time = (int)simple_strtol(s, NULL, 10);
-       else
-               retry_time = CONFIG_BOOT_RETRY_TIME;
-
-       if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
-               retry_time = CONFIG_BOOT_RETRY_MIN;
-}
-
-/***************************************************************************
- * reset command line timeout to retry_time seconds
- */
-void bootretry_reset_cmd_timeout(void)
-{
-       endtime = endtick(retry_time);
-}
-
-int bootretry_tstc_timeout(void)
-{
-       while (!tstc()) {       /* while no incoming data */
-               if (retry_time >= 0 && get_ticks() > endtime)
-                       return -ETIMEDOUT;
-               WATCHDOG_RESET();
-       }
-
-       return 0;
-}
-
-void bootretry_dont_retry(void)
-{
-       retry_time = -1;
-}
diff --git a/common/common_fit.c b/common/common_fit.c
deleted file mode 100644 (file)
index cde2dc4..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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 <image.h>
-#include <log.h>
-#include <linux/libfdt.h>
-
-ulong fdt_getprop_u32(const void *fdt, int node, const char *prop)
-{
-       const u32 *cell;
-       int len;
-
-       cell = fdt_getprop(fdt, node, prop, &len);
-       if (!cell || len != sizeof(*cell))
-               return FDT_ERROR;
-
-       return fdt32_to_cpu(*cell);
-}
-
-__weak int board_fit_config_name_match(const char *name)
-{
-       return -EINVAL;
-}
-
-/*
- * Iterate over all /configurations subnodes and call a platform specific
- * function to find the matching configuration.
- * Returns the node offset or a negative error number.
- */
-int fit_find_config_node(const void *fdt)
-{
-       const char *name;
-       int conf, node, len;
-       const char *dflt_conf_name;
-       const char *dflt_conf_desc = NULL;
-       int dflt_conf_node = -ENOENT;
-
-       conf = fdt_path_offset(fdt, FIT_CONFS_PATH);
-       if (conf < 0) {
-               debug("%s: Cannot find /configurations node: %d\n", __func__,
-                     conf);
-               return -EINVAL;
-       }
-
-       dflt_conf_name = fdt_getprop(fdt, conf, "default", &len);
-
-       for (node = fdt_first_subnode(fdt, conf);
-            node >= 0;
-            node = fdt_next_subnode(fdt, node)) {
-               name = fdt_getprop(fdt, node, "description", &len);
-               if (!name) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
-                       printf("%s: Missing FDT description in DTB\n",
-                              __func__);
-#endif
-                       return -EINVAL;
-               }
-
-               if (dflt_conf_name) {
-                       const char *node_name = fdt_get_name(fdt, node, NULL);
-                       if (strcmp(dflt_conf_name, node_name) == 0) {
-                               dflt_conf_node = node;
-                               dflt_conf_desc = name;
-                       }
-               }
-
-               if (board_fit_config_name_match(name))
-                       continue;
-
-               debug("Selecting config '%s'\n", name);
-
-               return node;
-       }
-
-       if (dflt_conf_node != -ENOENT) {
-               debug("Selecting default config '%s'\n", dflt_conf_desc);
-               return dflt_conf_node;
-       }
-
-       return -ENOENT;
-}
diff --git a/common/fdt_region.c b/common/fdt_region.c
deleted file mode 100644 (file)
index e4ef0ca..0000000
+++ /dev/null
@@ -1,671 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2013 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- */
-
-#include <fdt_support.h>
-#include <linux/libfdt_env.h>
-#include <fdt_region.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <linux/libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#define FDT_MAX_DEPTH  32
-
-static int str_in_list(const char *str, char * const list[], int count)
-{
-       int i;
-
-       for (i = 0; i < count; i++)
-               if (!strcmp(list[i], str))
-                       return 1;
-
-       return 0;
-}
-
-int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
-                    char * const exc_prop[], int exc_prop_count,
-                    struct fdt_region region[], int max_regions,
-                    char *path, int path_len, int add_string_tab)
-{
-       int stack[FDT_MAX_DEPTH] = { 0 };
-       char *end;
-       int nextoffset = 0;
-       uint32_t tag;
-       int count = 0;
-       int start = -1;
-       int depth = -1;
-       int want = 0;
-       int base = fdt_off_dt_struct(fdt);
-       bool expect_end = false;
-
-       end = path;
-       *end = '\0';
-       do {
-               const struct fdt_property *prop;
-               const char *name;
-               const char *str;
-               int include = 0;
-               int stop_at = 0;
-               int offset;
-               int len;
-
-               offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset);
-               stop_at = nextoffset;
-
-               /* If we see two root nodes, something is wrong */
-               if (expect_end && tag != FDT_END)
-                       return -FDT_ERR_BADLAYOUT;
-
-               switch (tag) {
-               case FDT_PROP:
-                       include = want >= 2;
-                       stop_at = offset;
-                       prop = fdt_get_property_by_offset(fdt, offset, NULL);
-                       str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
-                       if (!str)
-                               return -FDT_ERR_BADSTRUCTURE;
-                       if (str_in_list(str, exc_prop, exc_prop_count))
-                               include = 0;
-                       break;
-
-               case FDT_NOP:
-                       include = want >= 2;
-                       stop_at = offset;
-                       break;
-
-               case FDT_BEGIN_NODE:
-                       depth++;
-                       if (depth == FDT_MAX_DEPTH)
-                               return -FDT_ERR_BADSTRUCTURE;
-                       name = fdt_get_name(fdt, offset, &len);
-
-                       /* The root node must have an empty name */
-                       if (!depth && *name)
-                               return -FDT_ERR_BADLAYOUT;
-                       if (end - path + 2 + len >= path_len)
-                               return -FDT_ERR_NOSPACE;
-                       if (end != path + 1)
-                               *end++ = '/';
-                       strcpy(end, name);
-                       end += len;
-                       stack[depth] = want;
-                       if (want == 1)
-                               stop_at = offset;
-                       if (str_in_list(path, inc, inc_count))
-                               want = 2;
-                       else if (want)
-                               want--;
-                       else
-                               stop_at = offset;
-                       include = want;
-                       break;
-
-               case FDT_END_NODE:
-                       /* Depth must never go below -1 */
-                       if (depth < 0)
-                               return -FDT_ERR_BADSTRUCTURE;
-                       include = want;
-                       want = stack[depth--];
-                       while (end > path && *--end != '/')
-                               ;
-                       *end = '\0';
-                       if (depth == -1)
-                               expect_end = true;
-                       break;
-
-               case FDT_END:
-                       include = 1;
-                       break;
-               }
-
-               if (include && start == -1) {
-                       /* Should we merge with previous? */
-                       if (count && count <= max_regions &&
-                           offset == region[count - 1].offset +
-                                       region[count - 1].size - base)
-                               start = region[--count].offset - base;
-                       else
-                               start = offset;
-               }
-
-               if (!include && start != -1) {
-                       if (count < max_regions) {
-                               region[count].offset = base + start;
-                               region[count].size = stop_at - start;
-                       }
-                       count++;
-                       start = -1;
-               }
-       } while (tag != FDT_END);
-
-       if (nextoffset != fdt_size_dt_struct(fdt))
-               return -FDT_ERR_BADLAYOUT;
-
-       /* Add a region for the END tag and the string table */
-       if (count < max_regions) {
-               region[count].offset = base + start;
-               region[count].size = nextoffset - start;
-               if (add_string_tab)
-                       region[count].size += fdt_size_dt_strings(fdt);
-       }
-       count++;
-
-       return count;
-}
-
-/**
- * fdt_add_region() - Add a new region to our list
- * @info:      State information
- * @offset:    Start offset of region
- * @size:      Size of region
- *
- * The region is added if there is space, but in any case we increment the
- * count. If permitted, and the new region overlaps the last one, we merge
- * them.
- */
-static int fdt_add_region(struct fdt_region_state *info, int offset, int size)
-{
-       struct fdt_region *reg;
-
-       reg = info->region ? &info->region[info->count - 1] : NULL;
-       if (info->can_merge && info->count &&
-           info->count <= info->max_regions &&
-           reg && offset <= reg->offset + reg->size) {
-               reg->size = offset + size - reg->offset;
-       } else if (info->count++ < info->max_regions) {
-               if (reg) {
-                       reg++;
-                       reg->offset = offset;
-                       reg->size = size;
-               }
-       } else {
-               return -1;
-       }
-
-       return 0;
-}
-
-static int region_list_contains_offset(struct fdt_region_state *info,
-                                      const void *fdt, int target)
-{
-       struct fdt_region *reg;
-       int num;
-
-       target += fdt_off_dt_struct(fdt);
-       for (reg = info->region, num = 0; num < info->count; reg++, num++) {
-               if (target >= reg->offset && target < reg->offset + reg->size)
-                       return 1;
-       }
-
-       return 0;
-}
-
-/**
- * fdt_add_alias_regions() - Add regions covering the aliases that we want
- *
- * The /aliases node is not automatically included by fdtgrep unless the
- * command-line arguments cause to be included (or not excluded). However
- * aliases are special in that we generally want to include those which
- * reference a node that fdtgrep includes.
- *
- * In fact we want to include only aliases for those nodes still included in
- * the fdt, and drop the other aliases since they point to nodes that will not
- * be present.
- *
- * This function scans the aliases and adds regions for those which we want
- * to keep.
- *
- * @fdt: Device tree to scan
- * @region: List of regions
- * @count: Number of regions in the list so far (i.e. starting point for this
- *     function)
- * @max_regions: Maximum number of regions in @region list
- * @info: Place to put the region state
- * @return number of regions after processing, or -FDT_ERR_NOSPACE if we did
- * not have enough room in the regions table for the regions we wanted to add.
- */
-int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count,
-                         int max_regions, struct fdt_region_state *info)
-{
-       int base = fdt_off_dt_struct(fdt);
-       int node, node_end, offset;
-       int did_alias_header;
-
-       node = fdt_subnode_offset(fdt, 0, "aliases");
-       if (node < 0)
-               return -FDT_ERR_NOTFOUND;
-
-       /*
-        * Find the next node so that we know where the /aliases node ends. We
-        * need special handling if /aliases is the last node.
-        */
-       node_end = fdt_next_subnode(fdt, node);
-       if (node_end == -FDT_ERR_NOTFOUND)
-               /* Move back to the FDT_END_NODE tag of '/' */
-               node_end = fdt_size_dt_struct(fdt) - sizeof(fdt32_t) * 2;
-       else if (node_end < 0) /* other error */
-               return node_end;
-       node_end -= sizeof(fdt32_t);  /* Move to FDT_END_NODE tag of /aliases */
-
-       did_alias_header = 0;
-       info->region = region;
-       info->count = count;
-       info->can_merge = 0;
-       info->max_regions = max_regions;
-
-       for (offset = fdt_first_property_offset(fdt, node);
-            offset >= 0;
-            offset = fdt_next_property_offset(fdt, offset)) {
-               const struct fdt_property *prop;
-               const char *name;
-               int target, next;
-
-               prop = fdt_get_property_by_offset(fdt, offset, NULL);
-               name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
-               target = fdt_path_offset(fdt, name);
-               if (!region_list_contains_offset(info, fdt, target))
-                       continue;
-               next = fdt_next_property_offset(fdt, offset);
-               if (next < 0)
-                       next = node_end;
-
-               if (!did_alias_header) {
-                       fdt_add_region(info, base + node, 12);
-                       did_alias_header = 1;
-               }
-               fdt_add_region(info, base + offset, next - offset);
-       }
-
-       /* Add the FDT_END_NODE tag */
-       if (did_alias_header)
-               fdt_add_region(info, base + node_end, sizeof(fdt32_t));
-
-       return info->count < max_regions ? info->count : -FDT_ERR_NOSPACE;
-}
-
-/**
- * fdt_include_supernodes() - Include supernodes required by this node
- * @info:      State information
- * @depth:     Current stack depth
- *
- * When we decided to include a node or property which is not at the top
- * level, this function forces the inclusion of higher level nodes. For
- * example, given this tree:
- *
- * / {
- *     testing {
- *     }
- * }
- *
- * If we decide to include testing then we need the root node to have a valid
- * tree. This function adds those regions.
- */
-static int fdt_include_supernodes(struct fdt_region_state *info, int depth)
-{
-       int base = fdt_off_dt_struct(info->fdt);
-       int start, stop_at;
-       int i;
-
-       /*
-        * Work down the stack looking for supernodes that we didn't include.
-        * The algortihm here is actually pretty simple, since we know that
-        * no previous subnode had to include these nodes, or if it did, we
-        * marked them as included (on the stack) already.
-        */
-       for (i = 0; i <= depth; i++) {
-               if (!info->stack[i].included) {
-                       start = info->stack[i].offset;
-
-                       /* Add the FDT_BEGIN_NODE tag of this supernode */
-                       fdt_next_tag(info->fdt, start, &stop_at);
-                       if (fdt_add_region(info, base + start, stop_at - start))
-                               return -1;
-
-                       /* Remember that this supernode is now included */
-                       info->stack[i].included = 1;
-                       info->can_merge = 1;
-               }
-
-               /* Force (later) generation of the FDT_END_NODE tag */
-               if (!info->stack[i].want)
-                       info->stack[i].want = WANT_NODES_ONLY;
-       }
-
-       return 0;
-}
-
-enum {
-       FDT_DONE_NOTHING,
-       FDT_DONE_MEM_RSVMAP,
-       FDT_DONE_STRUCT,
-       FDT_DONE_END,
-       FDT_DONE_STRINGS,
-       FDT_DONE_ALL,
-};
-
-int fdt_first_region(const void *fdt,
-               int (*h_include)(void *priv, const void *fdt, int offset,
-                                int type, const char *data, int size),
-               void *priv, struct fdt_region *region,
-               char *path, int path_len, int flags,
-               struct fdt_region_state *info)
-{
-       struct fdt_region_ptrs *p = &info->ptrs;
-
-       /* Set up our state */
-       info->fdt = fdt;
-       info->can_merge = 1;
-       info->max_regions = 1;
-       info->start = -1;
-       p->want = WANT_NOTHING;
-       p->end = path;
-       *p->end = '\0';
-       p->nextoffset = 0;
-       p->depth = -1;
-       p->done = FDT_DONE_NOTHING;
-
-       return fdt_next_region(fdt, h_include, priv, region,
-                              path, path_len, flags, info);
-}
-
-/***********************************************************************
- *
- *     Theory of operation
- *
- * Note: in this description 'included' means that a node (or other part
- * of the tree) should be included in the region list, i.e. it will have
- * a region which covers its part of the tree.
- *
- * This function maintains some state from the last time it is called.
- * It checks the next part of the tree that it is supposed to look at
- * (p.nextoffset) to see if that should be included or not. When it
- * finds something to include, it sets info->start to its offset. This
- * marks the start of the region we want to include.
- *
- * Once info->start is set to the start (i.e. not -1), we continue
- * scanning until we find something that we don't want included. This
- * will be the end of a region. At this point we can close off the
- * region and add it to the list. So we do so, and reset info->start
- * to -1.
- *
- * One complication here is that we want to merge regions. So when we
- * come to add another region later, we may in fact merge it with the
- * previous one if one ends where the other starts.
- *
- * The function fdt_add_region() will return -1 if it fails to add the
- * region, because we already have a region ready to be returned, and
- * the new one cannot be merged in with it. In this case, we must return
- * the region we found, and wait for another call to this function.
- * When it comes, we will repeat the processing of the tag and again
- * try to add a region. This time it will succeed.
- *
- * The current state of the pointers (stack, offset, etc.) is maintained
- * in a ptrs member. At the start of every loop iteration we make a copy
- * of it.  The copy is then updated as the tag is processed. Only if we
- * get to the end of the loop iteration (and successfully call
- * fdt_add_region() if we need to) can we commit the changes we have
- * made to these pointers. For example, if we see an FDT_END_NODE tag,
- * we will decrement the depth value. But if we need to add a region
- * for this tag (let's say because the previous tag is included and this
- * FDT_END_NODE tag is not included) then we will only commit the result
- * if we were able to add the region. That allows us to retry again next
- * time.
- *
- * We keep track of a variable called 'want' which tells us what we want
- * to include when there is no specific information provided by the
- * h_include function for a particular property. This basically handles
- * the inclusion of properties which are pulled in by virtue of the node
- * they are in. So if you include a node, its properties are also
- * included.  In this case 'want' will be WANT_NODES_AND_PROPS. The
- * FDT_REG_DIRECT_SUBNODES feature also makes use of 'want'. While we
- * are inside the subnode, 'want' will be set to WANT_NODES_ONLY, so
- * that only the subnode's FDT_BEGIN_NODE and FDT_END_NODE tags will be
- * included, and properties will be skipped. If WANT_NOTHING is
- * selected, then we will just rely on what the h_include() function
- * tells us.
- *
- * Using 'want' we work out 'include', which tells us whether this
- * current tag should be included or not. As you can imagine, if the
- * value of 'include' changes, that means we are on a boundary between
- * nodes to include and nodes to exclude. At this point we either close
- * off a previous region and add it to the list, or mark the start of a
- * new region.
- *
- * Apart from the nodes, we have mem_rsvmap, the FDT_END tag and the
- * string list. Each of these dealt with as a whole (i.e. we create a
- * region for each if it is to be included). For mem_rsvmap we don't
- * allow it to merge with the first struct region. For the stringlist,
- * we don't allow it to merge with the last struct region (which
- * contains at minimum the FDT_END tag).
- *
- *********************************************************************/
-
-int fdt_next_region(const void *fdt,
-               int (*h_include)(void *priv, const void *fdt, int offset,
-                                int type, const char *data, int size),
-               void *priv, struct fdt_region *region,
-               char *path, int path_len, int flags,
-               struct fdt_region_state *info)
-{
-       int base = fdt_off_dt_struct(fdt);
-       int last_node = 0;
-       const char *str;
-
-       info->region = region;
-       info->count = 0;
-       if (info->ptrs.done < FDT_DONE_MEM_RSVMAP &&
-           (flags & FDT_REG_ADD_MEM_RSVMAP)) {
-               /* Add the memory reserve map into its own region */
-               if (fdt_add_region(info, fdt_off_mem_rsvmap(fdt),
-                                  fdt_off_dt_struct(fdt) -
-                                  fdt_off_mem_rsvmap(fdt)))
-                       return 0;
-               info->can_merge = 0;    /* Don't allow merging with this */
-               info->ptrs.done = FDT_DONE_MEM_RSVMAP;
-       }
-
-       /*
-        * Work through the tags one by one, deciding whether each needs to
-        * be included or not. We set the variable 'include' to indicate our
-        * decision. 'want' is used to track what we want to include - it
-        * allows us to pick up all the properties (and/or subnode tags) of
-        * a node.
-        */
-       while (info->ptrs.done < FDT_DONE_STRUCT) {
-               const struct fdt_property *prop;
-               struct fdt_region_ptrs p;
-               const char *name;
-               int include = 0;
-               int stop_at = 0;
-               uint32_t tag;
-               int offset;
-               int val;
-               int len;
-
-               /*
-                * Make a copy of our pointers. If we make it to the end of
-                * this block then we will commit them back to info->ptrs.
-                * Otherwise we can try again from the same starting state
-                * next time we are called.
-                */
-               p = info->ptrs;
-
-               /*
-                * Find the tag, and the offset of the next one. If we need to
-                * stop including tags, then by default we stop *after*
-                * including the current tag
-                */
-               offset = p.nextoffset;
-               tag = fdt_next_tag(fdt, offset, &p.nextoffset);
-               stop_at = p.nextoffset;
-
-               switch (tag) {
-               case FDT_PROP:
-                       stop_at = offset;
-                       prop = fdt_get_property_by_offset(fdt, offset, NULL);
-                       str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
-                       val = h_include(priv, fdt, last_node, FDT_IS_PROP, str,
-                                           strlen(str) + 1);
-                       if (val == -1) {
-                               include = p.want >= WANT_NODES_AND_PROPS;
-                       } else {
-                               include = val;
-                               /*
-                                * Make sure we include the } for this block.
-                                * It might be more correct to have this done
-                                * by the call to fdt_include_supernodes() in
-                                * the case where it adds the node we are
-                                * currently in, but this is equivalent.
-                                */
-                               if ((flags & FDT_REG_SUPERNODES) && val &&
-                                   !p.want)
-                                       p.want = WANT_NODES_ONLY;
-                       }
-
-                       /* Value grepping is not yet supported */
-                       break;
-
-               case FDT_NOP:
-                       include = p.want >= WANT_NODES_AND_PROPS;
-                       stop_at = offset;
-                       break;
-
-               case FDT_BEGIN_NODE:
-                       last_node = offset;
-                       p.depth++;
-                       if (p.depth == FDT_MAX_DEPTH)
-                               return -FDT_ERR_BADSTRUCTURE;
-                       name = fdt_get_name(fdt, offset, &len);
-                       if (p.end - path + 2 + len >= path_len)
-                               return -FDT_ERR_NOSPACE;
-
-                       /* Build the full path of this node */
-                       if (p.end != path + 1)
-                               *p.end++ = '/';
-                       strcpy(p.end, name);
-                       p.end += len;
-                       info->stack[p.depth].want = p.want;
-                       info->stack[p.depth].offset = offset;
-
-                       /*
-                        * If we are not intending to include this node unless
-                        * it matches, make sure we stop *before* its tag.
-                        */
-                       if (p.want == WANT_NODES_ONLY ||
-                           !(flags & (FDT_REG_DIRECT_SUBNODES |
-                                      FDT_REG_ALL_SUBNODES))) {
-                               stop_at = offset;
-                               p.want = WANT_NOTHING;
-                       }
-                       val = h_include(priv, fdt, offset, FDT_IS_NODE, path,
-                                       p.end - path + 1);
-
-                       /* Include this if requested */
-                       if (val) {
-                               p.want = (flags & FDT_REG_ALL_SUBNODES) ?
-                                       WANT_ALL_NODES_AND_PROPS :
-                                       WANT_NODES_AND_PROPS;
-                       }
-
-                       /* If not requested, decay our 'p.want' value */
-                       else if (p.want) {
-                               if (p.want != WANT_ALL_NODES_AND_PROPS)
-                                       p.want--;
-
-                       /* Not including this tag, so stop now */
-                       } else {
-                               stop_at = offset;
-                       }
-
-                       /*
-                        * Decide whether to include this tag, and update our
-                        * stack with the state for this node
-                        */
-                       include = p.want;
-                       info->stack[p.depth].included = include;
-                       break;
-
-               case FDT_END_NODE:
-                       include = p.want;
-                       if (p.depth < 0)
-                               return -FDT_ERR_BADSTRUCTURE;
-
-                       /*
-                        * If we don't want this node, stop right away, unless
-                        * we are including subnodes
-                        */
-                       if (!p.want && !(flags & FDT_REG_DIRECT_SUBNODES))
-                               stop_at = offset;
-                       p.want = info->stack[p.depth].want;
-                       p.depth--;
-                       while (p.end > path && *--p.end != '/')
-                               ;
-                       *p.end = '\0';
-                       break;
-
-               case FDT_END:
-                       /* We always include the end tag */
-                       include = 1;
-                       p.done = FDT_DONE_STRUCT;
-                       break;
-               }
-
-               /* If this tag is to be included, mark it as region start */
-               if (include && info->start == -1) {
-                       /* Include any supernodes required by this one */
-                       if (flags & FDT_REG_SUPERNODES) {
-                               if (fdt_include_supernodes(info, p.depth))
-                                       return 0;
-                       }
-                       info->start = offset;
-               }
-
-               /*
-                * If this tag is not to be included, finish up the current
-                * region.
-                */
-               if (!include && info->start != -1) {
-                       if (fdt_add_region(info, base + info->start,
-                                          stop_at - info->start))
-                               return 0;
-                       info->start = -1;
-                       info->can_merge = 1;
-               }
-
-               /* If we have made it this far, we can commit our pointers */
-               info->ptrs = p;
-       }
-
-       /* Add a region for the END tag and a separate one for string table */
-       if (info->ptrs.done < FDT_DONE_END) {
-               if (info->ptrs.nextoffset != fdt_size_dt_struct(fdt))
-                       return -FDT_ERR_BADSTRUCTURE;
-
-               if (fdt_add_region(info, base + info->start,
-                                  info->ptrs.nextoffset - info->start))
-                       return 0;
-               info->ptrs.done++;
-       }
-       if (info->ptrs.done < FDT_DONE_STRINGS) {
-               if (flags & FDT_REG_ADD_STRING_TAB) {
-                       info->can_merge = 0;
-                       if (fdt_off_dt_strings(fdt) <
-                           base + info->ptrs.nextoffset)
-                               return -FDT_ERR_BADLAYOUT;
-                       if (fdt_add_region(info, fdt_off_dt_strings(fdt),
-                                          fdt_size_dt_strings(fdt)))
-                               return 0;
-               }
-               info->ptrs.done++;
-       }
-
-       return info->count > 0 ? 0 : -FDT_ERR_NOTFOUND;
-}
diff --git a/common/image-android-dt.c b/common/image-android-dt.c
deleted file mode 100644 (file)
index a2d52df..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2018 Linaro Ltd.
- * Sam Protsenko <semen.protsenko@linaro.org>
- */
-
-#include <image-android-dt.h>
-#include <dt_table.h>
-#include <common.h>
-#include <linux/libfdt.h>
-#include <mapmem.h>
-
-/**
- * Check if image header is correct.
- *
- * @param hdr_addr Start address of DT image
- * @return true if header is correct or false if header is incorrect
- */
-bool android_dt_check_header(ulong hdr_addr)
-{
-       const struct dt_table_header *hdr;
-       u32 magic;
-
-       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
-       magic = fdt32_to_cpu(hdr->magic);
-       unmap_sysmem(hdr);
-
-       return magic == DT_TABLE_MAGIC;
-}
-
-/**
- * Get the address of FDT (dtb or dtbo) in memory by its index in image.
- *
- * @param hdr_addr Start address of DT image
- * @param index Index of desired FDT in image (starting from 0)
- * @param[out] addr If not NULL, will contain address to specified FDT
- * @param[out] size If not NULL, will contain size of specified FDT
- *
- * @return true on success or false on error
- */
-bool android_dt_get_fdt_by_index(ulong hdr_addr, u32 index, ulong *addr,
-                                u32 *size)
-{
-       const struct dt_table_header *hdr;
-       const struct dt_table_entry *e;
-       u32 entry_count, entries_offset, entry_size;
-       ulong e_addr;
-       u32 dt_offset, dt_size;
-
-       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
-       entry_count = fdt32_to_cpu(hdr->dt_entry_count);
-       entries_offset = fdt32_to_cpu(hdr->dt_entries_offset);
-       entry_size = fdt32_to_cpu(hdr->dt_entry_size);
-       unmap_sysmem(hdr);
-
-       if (index >= entry_count) {
-               printf("Error: index >= dt_entry_count (%u >= %u)\n", index,
-                      entry_count);
-               return false;
-       }
-
-       e_addr = hdr_addr + entries_offset + index * entry_size;
-       e = map_sysmem(e_addr, sizeof(*e));
-       dt_offset = fdt32_to_cpu(e->dt_offset);
-       dt_size = fdt32_to_cpu(e->dt_size);
-       unmap_sysmem(e);
-
-       if (addr)
-               *addr = hdr_addr + dt_offset;
-       if (size)
-               *size = dt_size;
-
-       return true;
-}
-
-#if !defined(CONFIG_SPL_BUILD)
-static void android_dt_print_fdt_info(const struct fdt_header *fdt)
-{
-       u32 fdt_size;
-       int root_node_off;
-       const char *compatible;
-
-       root_node_off = fdt_path_offset(fdt, "/");
-       if (root_node_off < 0) {
-               printf("Error: Root node not found\n");
-               return;
-       }
-
-       fdt_size = fdt_totalsize(fdt);
-       compatible = fdt_getprop(fdt, root_node_off, "compatible",
-                                NULL);
-
-       printf("           (FDT)size = %d\n", fdt_size);
-       printf("     (FDT)compatible = %s\n",
-              compatible ? compatible : "(unknown)");
-}
-
-/**
- * Print information about DT image structure.
- *
- * @param hdr_addr Start address of DT image
- */
-void android_dt_print_contents(ulong hdr_addr)
-{
-       const struct dt_table_header *hdr;
-       u32 entry_count, entries_offset, entry_size;
-       u32 i;
-
-       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
-       entry_count = fdt32_to_cpu(hdr->dt_entry_count);
-       entries_offset = fdt32_to_cpu(hdr->dt_entries_offset);
-       entry_size = fdt32_to_cpu(hdr->dt_entry_size);
-
-       /* Print image header info */
-       printf("dt_table_header:\n");
-       printf("               magic = %08x\n", fdt32_to_cpu(hdr->magic));
-       printf("          total_size = %d\n", fdt32_to_cpu(hdr->total_size));
-       printf("         header_size = %d\n", fdt32_to_cpu(hdr->header_size));
-       printf("       dt_entry_size = %d\n", entry_size);
-       printf("      dt_entry_count = %d\n", entry_count);
-       printf("   dt_entries_offset = %d\n", entries_offset);
-       printf("           page_size = %d\n", fdt32_to_cpu(hdr->page_size));
-       printf("             version = %d\n", fdt32_to_cpu(hdr->version));
-
-       unmap_sysmem(hdr);
-
-       /* Print image entries info */
-       for (i = 0; i < entry_count; ++i) {
-               const ulong e_addr = hdr_addr + entries_offset + i * entry_size;
-               const struct dt_table_entry *e;
-               const struct fdt_header *fdt;
-               u32 dt_offset, dt_size;
-               u32 j;
-
-               e = map_sysmem(e_addr, sizeof(*e));
-               dt_offset = fdt32_to_cpu(e->dt_offset);
-               dt_size = fdt32_to_cpu(e->dt_size);
-
-               printf("dt_table_entry[%d]:\n", i);
-               printf("             dt_size = %d\n", dt_size);
-               printf("           dt_offset = %d\n", dt_offset);
-               printf("                  id = %08x\n", fdt32_to_cpu(e->id));
-               printf("                 rev = %08x\n", fdt32_to_cpu(e->rev));
-               for (j = 0; j < 4; ++j) {
-                       printf("           custom[%d] = %08x\n", j,
-                              fdt32_to_cpu(e->custom[j]));
-               }
-
-               unmap_sysmem(e);
-
-               /* Print FDT info for this entry */
-               fdt = map_sysmem(hdr_addr + dt_offset, sizeof(*fdt));
-               android_dt_print_fdt_info(fdt);
-               unmap_sysmem(fdt);
-       }
-}
-#endif
diff --git a/common/image-android.c b/common/image-android.c
deleted file mode 100644 (file)
index 1fbbbba..0000000
+++ /dev/null
@@ -1,539 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- */
-
-#include <common.h>
-#include <env.h>
-#include <image.h>
-#include <image-android-dt.h>
-#include <android_image.h>
-#include <malloc.h>
-#include <errno.h>
-#include <asm/unaligned.h>
-#include <mapmem.h>
-#include <linux/libfdt.h>
-
-#define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR      0x10008000
-
-static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
-
-static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
-{
-       /*
-        * All the Android tools that generate a boot.img use this
-        * address as the default.
-        *
-        * Even though it doesn't really make a lot of sense, and it
-        * might be valid on some platforms, we treat that adress as
-        * the default value for this field, and try to execute the
-        * kernel in place in such a case.
-        *
-        * Otherwise, we will return the actual value set by the user.
-        */
-       if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR)
-               return (ulong)hdr + hdr->page_size;
-
-       /*
-        * abootimg creates images where all load addresses are 0
-        * and we need to fix them.
-        */
-       if (hdr->kernel_addr == 0 && hdr->ramdisk_addr == 0)
-               return env_get_ulong("kernel_addr_r", 16, 0);
-
-       return hdr->kernel_addr;
-}
-
-/**
- * android_image_get_kernel() - processes kernel part of Android boot images
- * @hdr:       Pointer to image header, which is at the start
- *                     of the image.
- * @verify:    Checksum verification flag. Currently unimplemented.
- * @os_data:   Pointer to a ulong variable, will hold os data start
- *                     address.
- * @os_len:    Pointer to a ulong variable, will hold os data length.
- *
- * This function returns the os image's start address and length. Also,
- * it appends the kernel command line to the bootargs env variable.
- *
- * Return: Zero, os start address and length on success,
- *             otherwise on failure.
- */
-int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
-                            ulong *os_data, ulong *os_len)
-{
-       u32 kernel_addr = android_image_get_kernel_addr(hdr);
-       const struct image_header *ihdr = (const struct image_header *)
-               ((uintptr_t)hdr + hdr->page_size);
-
-       /*
-        * Not all Android tools use the id field for signing the image with
-        * sha1 (or anything) so we don't check it. It is not obvious that the
-        * string is null terminated so we take care of this.
-        */
-       strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE);
-       andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0';
-       if (strlen(andr_tmp_str))
-               printf("Android's image name: %s\n", andr_tmp_str);
-
-       printf("Kernel load addr 0x%08x size %u KiB\n",
-              kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
-
-       int len = 0;
-       if (*hdr->cmdline) {
-               printf("Kernel command line: %s\n", hdr->cmdline);
-               len += strlen(hdr->cmdline);
-       }
-
-       char *bootargs = env_get("bootargs");
-       if (bootargs)
-               len += strlen(bootargs);
-
-       char *newbootargs = malloc(len + 2);
-       if (!newbootargs) {
-               puts("Error: malloc in android_image_get_kernel failed!\n");
-               return -ENOMEM;
-       }
-       *newbootargs = '\0';
-
-       if (bootargs) {
-               strcpy(newbootargs, bootargs);
-               strcat(newbootargs, " ");
-       }
-       if (*hdr->cmdline)
-               strcat(newbootargs, hdr->cmdline);
-
-       env_set("bootargs", newbootargs);
-
-       if (os_data) {
-               if (image_get_magic(ihdr) == IH_MAGIC) {
-                       *os_data = image_get_data(ihdr);
-               } else {
-                       *os_data = (ulong)hdr;
-                       *os_data += hdr->page_size;
-               }
-       }
-       if (os_len) {
-               if (image_get_magic(ihdr) == IH_MAGIC)
-                       *os_len = image_get_data_size(ihdr);
-               else
-                       *os_len = hdr->kernel_size;
-       }
-       return 0;
-}
-
-int android_image_check_header(const struct andr_img_hdr *hdr)
-{
-       return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE);
-}
-
-ulong android_image_get_end(const struct andr_img_hdr *hdr)
-{
-       ulong end;
-
-       /*
-        * The header takes a full page, the remaining components are aligned
-        * on page boundary
-        */
-       end = (ulong)hdr;
-       end += hdr->page_size;
-       end += ALIGN(hdr->kernel_size, hdr->page_size);
-       end += ALIGN(hdr->ramdisk_size, hdr->page_size);
-       end += ALIGN(hdr->second_size, hdr->page_size);
-
-       if (hdr->header_version >= 1)
-               end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
-
-       if (hdr->header_version >= 2)
-               end += ALIGN(hdr->dtb_size, hdr->page_size);
-
-       return end;
-}
-
-ulong android_image_get_kload(const struct andr_img_hdr *hdr)
-{
-       return android_image_get_kernel_addr(hdr);
-}
-
-ulong android_image_get_kcomp(const struct andr_img_hdr *hdr)
-{
-       const void *p = (void *)((uintptr_t)hdr + hdr->page_size);
-
-       if (image_get_magic((image_header_t *)p) == IH_MAGIC)
-               return image_get_comp((image_header_t *)p);
-       else if (get_unaligned_le32(p) == LZ4F_MAGIC)
-               return IH_COMP_LZ4;
-       else
-               return image_decomp_type(p, sizeof(u32));
-}
-
-int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
-                             ulong *rd_data, ulong *rd_len)
-{
-       if (!hdr->ramdisk_size) {
-               *rd_data = *rd_len = 0;
-               return -1;
-       }
-
-       printf("RAM disk load addr 0x%08x size %u KiB\n",
-              hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
-
-       *rd_data = (unsigned long)hdr;
-       *rd_data += hdr->page_size;
-       *rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
-
-       *rd_len = hdr->ramdisk_size;
-       return 0;
-}
-
-int android_image_get_second(const struct andr_img_hdr *hdr,
-                             ulong *second_data, ulong *second_len)
-{
-       if (!hdr->second_size) {
-               *second_data = *second_len = 0;
-               return -1;
-       }
-
-       *second_data = (unsigned long)hdr;
-       *second_data += hdr->page_size;
-       *second_data += ALIGN(hdr->kernel_size, hdr->page_size);
-       *second_data += ALIGN(hdr->ramdisk_size, hdr->page_size);
-
-       printf("second address is 0x%lx\n",*second_data);
-
-       *second_len = hdr->second_size;
-       return 0;
-}
-
-/**
- * android_image_get_dtbo() - Get address and size of recovery DTBO image.
- * @hdr_addr: Boot image header address
- * @addr: If not NULL, will contain address of recovery DTBO image
- * @size: If not NULL, will contain size of recovery DTBO image
- *
- * Get the address and size of DTBO image in "Recovery DTBO" area of Android
- * Boot Image in RAM. The format of this image is Android DTBO (see
- * corresponding "DTB/DTBO Partitions" AOSP documentation for details). Once
- * the address is obtained from this function, one can use 'adtimg' U-Boot
- * command or android_dt_*() functions to extract desired DTBO blob.
- *
- * This DTBO (included in boot image) is only needed for non-A/B devices, and it
- * only can be found in recovery image. On A/B devices we can always rely on
- * "dtbo" partition. See "Including DTBO in Recovery for Non-A/B Devices" in
- * AOSP documentation for details.
- *
- * Return: true on success or false on error.
- */
-bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size)
-{
-       const struct andr_img_hdr *hdr;
-       ulong dtbo_img_addr;
-       bool ret = true;
-
-       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
-       if (android_image_check_header(hdr)) {
-               printf("Error: Boot Image header is incorrect\n");
-               ret = false;
-               goto exit;
-       }
-
-       if (hdr->header_version < 1) {
-               printf("Error: header_version must be >= 1 to get dtbo\n");
-               ret = false;
-               goto exit;
-       }
-
-       if (hdr->recovery_dtbo_size == 0) {
-               printf("Error: recovery_dtbo_size is 0\n");
-               ret = false;
-               goto exit;
-       }
-
-       /* Calculate the address of DTB area in boot image */
-       dtbo_img_addr = hdr_addr;
-       dtbo_img_addr += hdr->page_size;
-       dtbo_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
-       dtbo_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
-       dtbo_img_addr += ALIGN(hdr->second_size, hdr->page_size);
-
-       if (addr)
-               *addr = dtbo_img_addr;
-       if (size)
-               *size = hdr->recovery_dtbo_size;
-
-exit:
-       unmap_sysmem(hdr);
-       return ret;
-}
-
-/**
- * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image.
- * @hdr_addr: Boot image header address
- * @addr: Will contain the address of DTB area in boot image
- *
- * Return: true on success or false on fail.
- */
-static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong *addr)
-{
-       const struct andr_img_hdr *hdr;
-       ulong dtb_img_addr;
-       bool ret = true;
-
-       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
-       if (android_image_check_header(hdr)) {
-               printf("Error: Boot Image header is incorrect\n");
-               ret = false;
-               goto exit;
-       }
-
-       if (hdr->header_version < 2) {
-               printf("Error: header_version must be >= 2 to get dtb\n");
-               ret = false;
-               goto exit;
-       }
-
-       if (hdr->dtb_size == 0) {
-               printf("Error: dtb_size is 0\n");
-               ret = false;
-               goto exit;
-       }
-
-       /* Calculate the address of DTB area in boot image */
-       dtb_img_addr = hdr_addr;
-       dtb_img_addr += hdr->page_size;
-       dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
-       dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
-       dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size);
-       dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
-
-       *addr = dtb_img_addr;
-
-exit:
-       unmap_sysmem(hdr);
-       return ret;
-}
-
-/**
- * android_image_get_dtb_by_index() - Get address and size of blob in DTB area.
- * @hdr_addr: Boot image header address
- * @index: Index of desired DTB in DTB area (starting from 0)
- * @addr: If not NULL, will contain address to specified DTB
- * @size: If not NULL, will contain size of specified DTB
- *
- * Get the address and size of DTB blob by its index in DTB area of Android
- * Boot Image in RAM.
- *
- * Return: true on success or false on error.
- */
-bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr,
-                                   u32 *size)
-{
-       const struct andr_img_hdr *hdr;
-       bool res;
-       ulong dtb_img_addr;     /* address of DTB part in boot image */
-       u32 dtb_img_size;       /* size of DTB payload in boot image */
-       ulong dtb_addr;         /* address of DTB blob with specified index  */
-       u32 i;                  /* index iterator */
-
-       res = android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr);
-       if (!res)
-               return false;
-
-       /* Check if DTB area of boot image is in DTBO format */
-       if (android_dt_check_header(dtb_img_addr)) {
-               return android_dt_get_fdt_by_index(dtb_img_addr, index, addr,
-                                                  size);
-       }
-
-       /* Find out the address of DTB with specified index in concat blobs */
-       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
-       dtb_img_size = hdr->dtb_size;
-       unmap_sysmem(hdr);
-       i = 0;
-       dtb_addr = dtb_img_addr;
-       while (dtb_addr < dtb_img_addr + dtb_img_size) {
-               const struct fdt_header *fdt;
-               u32 dtb_size;
-
-               fdt = map_sysmem(dtb_addr, sizeof(*fdt));
-               if (fdt_check_header(fdt) != 0) {
-                       unmap_sysmem(fdt);
-                       printf("Error: Invalid FDT header for index %u\n", i);
-                       return false;
-               }
-
-               dtb_size = fdt_totalsize(fdt);
-               unmap_sysmem(fdt);
-
-               if (i == index) {
-                       if (size)
-                               *size = dtb_size;
-                       if (addr)
-                               *addr = dtb_addr;
-                       return true;
-               }
-
-               dtb_addr += dtb_size;
-               ++i;
-       }
-
-       printf("Error: Index is out of bounds (%u/%u)\n", index, i);
-       return false;
-}
-
-#if !defined(CONFIG_SPL_BUILD)
-/**
- * android_print_contents - prints out the contents of the Android format image
- * @hdr: pointer to the Android format image header
- *
- * android_print_contents() formats a multi line Android image contents
- * description.
- * The routine prints out Android image properties
- *
- * returns:
- *     no returned results
- */
-void android_print_contents(const struct andr_img_hdr *hdr)
-{
-       const char * const p = IMAGE_INDENT_STRING;
-       /* os_version = ver << 11 | lvl */
-       u32 os_ver = hdr->os_version >> 11;
-       u32 os_lvl = hdr->os_version & ((1U << 11) - 1);
-
-       printf("%skernel size:          %x\n", p, hdr->kernel_size);
-       printf("%skernel address:       %x\n", p, hdr->kernel_addr);
-       printf("%sramdisk size:         %x\n", p, hdr->ramdisk_size);
-       printf("%sramdisk address:      %x\n", p, hdr->ramdisk_addr);
-       printf("%ssecond size:          %x\n", p, hdr->second_size);
-       printf("%ssecond address:       %x\n", p, hdr->second_addr);
-       printf("%stags address:         %x\n", p, hdr->tags_addr);
-       printf("%spage size:            %x\n", p, hdr->page_size);
-       /* ver = A << 14 | B << 7 | C         (7 bits for each of A, B, C)
-        * lvl = ((Y - 2000) & 127) << 4 | M  (7 bits for Y, 4 bits for M) */
-       printf("%sos_version:           %x (ver: %u.%u.%u, level: %u.%u)\n",
-              p, hdr->os_version,
-              (os_ver >> 7) & 0x7F, (os_ver >> 14) & 0x7F, os_ver & 0x7F,
-              (os_lvl >> 4) + 2000, os_lvl & 0x0F);
-       printf("%sname:                 %s\n", p, hdr->name);
-       printf("%scmdline:              %s\n", p, hdr->cmdline);
-       printf("%sheader_version:       %d\n", p, hdr->header_version);
-
-       if (hdr->header_version >= 1) {
-               printf("%srecovery dtbo size:   %x\n", p,
-                      hdr->recovery_dtbo_size);
-               printf("%srecovery dtbo offset: %llx\n", p,
-                      hdr->recovery_dtbo_offset);
-               printf("%sheader size:          %x\n", p,
-                      hdr->header_size);
-       }
-
-       if (hdr->header_version >= 2) {
-               printf("%sdtb size:             %x\n", p, hdr->dtb_size);
-               printf("%sdtb addr:             %llx\n", p, hdr->dtb_addr);
-       }
-}
-
-/**
- * android_image_print_dtb_info - Print info for one DTB blob in DTB area.
- * @fdt: DTB header
- * @index: Number of DTB blob in DTB area.
- *
- * Return: true on success or false on error.
- */
-static bool android_image_print_dtb_info(const struct fdt_header *fdt,
-                                        u32 index)
-{
-       int root_node_off;
-       u32 fdt_size;
-       const char *model;
-       const char *compatible;
-
-       root_node_off = fdt_path_offset(fdt, "/");
-       if (root_node_off < 0) {
-               printf("Error: Root node not found\n");
-               return false;
-       }
-
-       fdt_size = fdt_totalsize(fdt);
-       compatible = fdt_getprop(fdt, root_node_off, "compatible",
-                                NULL);
-       model = fdt_getprop(fdt, root_node_off, "model", NULL);
-
-       printf(" - DTB #%u:\n", index);
-       printf("           (DTB)size = %d\n", fdt_size);
-       printf("          (DTB)model = %s\n", model ? model : "(unknown)");
-       printf("     (DTB)compatible = %s\n",
-              compatible ? compatible : "(unknown)");
-
-       return true;
-}
-
-/**
- * android_image_print_dtb_contents() - Print info for DTB blobs in DTB area.
- * @hdr_addr: Boot image header address
- *
- * DTB payload in Android Boot Image v2+ can be in one of following formats:
- *   1. Concatenated DTB blobs
- *   2. Android DTBO format (see CONFIG_CMD_ADTIMG for details)
- *
- * This function does next:
- *   1. Prints out the format used in DTB area
- *   2. Iterates over all DTB blobs in DTB area and prints out the info for
- *      each blob.
- *
- * Return: true on success or false on error.
- */
-bool android_image_print_dtb_contents(ulong hdr_addr)
-{
-       const struct andr_img_hdr *hdr;
-       bool res;
-       ulong dtb_img_addr;     /* address of DTB part in boot image */
-       u32 dtb_img_size;       /* size of DTB payload in boot image */
-       ulong dtb_addr;         /* address of DTB blob with specified index  */
-       u32 i;                  /* index iterator */
-
-       res = android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr);
-       if (!res)
-               return false;
-
-       /* Check if DTB area of boot image is in DTBO format */
-       if (android_dt_check_header(dtb_img_addr)) {
-               printf("## DTB area contents (DTBO format):\n");
-               android_dt_print_contents(dtb_img_addr);
-               return true;
-       }
-
-       printf("## DTB area contents (concat format):\n");
-
-       /* Iterate over concatenated DTB blobs */
-       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
-       dtb_img_size = hdr->dtb_size;
-       unmap_sysmem(hdr);
-       i = 0;
-       dtb_addr = dtb_img_addr;
-       while (dtb_addr < dtb_img_addr + dtb_img_size) {
-               const struct fdt_header *fdt;
-               u32 dtb_size;
-
-               fdt = map_sysmem(dtb_addr, sizeof(*fdt));
-               if (fdt_check_header(fdt) != 0) {
-                       unmap_sysmem(fdt);
-                       printf("Error: Invalid FDT header for index %u\n", i);
-                       return false;
-               }
-
-               res = android_image_print_dtb_info(fdt, i);
-               if (!res) {
-                       unmap_sysmem(fdt);
-                       return false;
-               }
-
-               dtb_size = fdt_totalsize(fdt);
-               unmap_sysmem(fdt);
-               dtb_addr += dtb_size;
-               ++i;
-       }
-
-       return true;
-}
-#endif
diff --git a/common/image-board.c b/common/image-board.c
deleted file mode 100644 (file)
index ddf30c6..0000000
+++ /dev/null
@@ -1,956 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Image code used by boards (and not host tools)
- *
- * (C) Copyright 2008 Semihalf
- *
- * (C) Copyright 2000-2006
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#include <common.h>
-#include <bootstage.h>
-#include <cpu_func.h>
-#include <env.h>
-#include <fpga.h>
-#include <image.h>
-#include <mapmem.h>
-#include <rtc.h>
-#include <watchdog.h>
-#include <asm/cache.h>
-#include <asm/global_data.h>
-
-#ifndef CONFIG_SYS_BARGSIZE
-#define CONFIG_SYS_BARGSIZE 512
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/**
- * image_get_ramdisk - get and verify ramdisk image
- * @rd_addr: ramdisk image start address
- * @arch: expected ramdisk architecture
- * @verify: checksum verification flag
- *
- * image_get_ramdisk() returns a pointer to the verified ramdisk image
- * header. Routine receives image start address and expected architecture
- * flag. Verification done covers data and header integrity and os/type/arch
- * fields checking.
- *
- * returns:
- *     pointer to a ramdisk image header, if image was found and valid
- *     otherwise, return NULL
- */
-static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch,
-                                              int verify)
-{
-       const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
-
-       if (!image_check_magic(rd_hdr)) {
-               puts("Bad Magic Number\n");
-               bootstage_error(BOOTSTAGE_ID_RD_MAGIC);
-               return NULL;
-       }
-
-       if (!image_check_hcrc(rd_hdr)) {
-               puts("Bad Header Checksum\n");
-               bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
-               return NULL;
-       }
-
-       bootstage_mark(BOOTSTAGE_ID_RD_MAGIC);
-       image_print_contents(rd_hdr);
-
-       if (verify) {
-               puts("   Verifying Checksum ... ");
-               if (!image_check_dcrc(rd_hdr)) {
-                       puts("Bad Data CRC\n");
-                       bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM);
-                       return NULL;
-               }
-               puts("OK\n");
-       }
-
-       bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
-
-       if (!image_check_os(rd_hdr, IH_OS_LINUX) ||
-           !image_check_arch(rd_hdr, arch) ||
-           !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) {
-               printf("No Linux %s Ramdisk Image\n",
-                      genimg_get_arch_name(arch));
-               bootstage_error(BOOTSTAGE_ID_RAMDISK);
-               return NULL;
-       }
-
-       return rd_hdr;
-}
-
-/*****************************************************************************/
-/* Shared dual-format routines */
-/*****************************************************************************/
-ulong image_load_addr = CONFIG_SYS_LOAD_ADDR;  /* Default Load Address */
-ulong image_save_addr;                 /* Default Save Address */
-ulong image_save_size;                 /* Default Save Size (in bytes) */
-
-static int on_loadaddr(const char *name, const char *value, enum env_op op,
-                      int flags)
-{
-       switch (op) {
-       case env_op_create:
-       case env_op_overwrite:
-               image_load_addr = hextoul(value, NULL);
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr);
-
-ulong env_get_bootm_low(void)
-{
-       char *s = env_get("bootm_low");
-
-       if (s) {
-               ulong tmp = hextoul(s, NULL);
-               return tmp;
-       }
-
-#if defined(CONFIG_SYS_SDRAM_BASE)
-       return CONFIG_SYS_SDRAM_BASE;
-#elif defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_RISCV)
-       return gd->bd->bi_dram[0].start;
-#else
-       return 0;
-#endif
-}
-
-phys_size_t env_get_bootm_size(void)
-{
-       phys_size_t tmp, size;
-       phys_addr_t start;
-       char *s = env_get("bootm_size");
-
-       if (s) {
-               tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
-               return tmp;
-       }
-
-       start = gd->ram_base;
-       size = gd->ram_size;
-
-       if (start + size > gd->ram_top)
-               size = gd->ram_top - start;
-
-       s = env_get("bootm_low");
-       if (s)
-               tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
-       else
-               tmp = start;
-
-       return size - (tmp - start);
-}
-
-phys_size_t env_get_bootm_mapsize(void)
-{
-       phys_size_t tmp;
-       char *s = env_get("bootm_mapsize");
-
-       if (s) {
-               tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
-               return tmp;
-       }
-
-#if defined(CONFIG_SYS_BOOTMAPSZ)
-       return CONFIG_SYS_BOOTMAPSZ;
-#else
-       return env_get_bootm_size();
-#endif
-}
-
-void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
-{
-       if (to == from)
-               return;
-
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-       if (to > from) {
-               from += len;
-               to += len;
-       }
-       while (len > 0) {
-               size_t tail = (len > chunksz) ? chunksz : len;
-
-               WATCHDOG_RESET();
-               if (to > from) {
-                       to -= tail;
-                       from -= tail;
-               }
-               memmove(to, from, tail);
-               if (to < from) {
-                       to += tail;
-                       from += tail;
-               }
-               len -= tail;
-       }
-#else  /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
-       memmove(to, from, len);
-#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
-}
-
-/**
- * genimg_get_kernel_addr_fit - get the real kernel address and return 2
- *                              FIT strings
- * @img_addr: a string might contain real image address
- * @fit_uname_config: double pointer to a char, will hold pointer to a
- *                    configuration unit name
- * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage
- *                    name
- *
- * genimg_get_kernel_addr_fit get the real kernel start address from a string
- * which is normally the first argv of bootm/bootz
- *
- * returns:
- *     kernel start address
- */
-ulong genimg_get_kernel_addr_fit(char * const img_addr,
-                                const char **fit_uname_config,
-                                const char **fit_uname_kernel)
-{
-       ulong kernel_addr;
-
-       /* find out kernel image address */
-       if (!img_addr) {
-               kernel_addr = image_load_addr;
-               debug("*  kernel: default image load address = 0x%08lx\n",
-                     image_load_addr);
-       } else if (CONFIG_IS_ENABLED(FIT) &&
-                  fit_parse_conf(img_addr, image_load_addr, &kernel_addr,
-                                 fit_uname_config)) {
-               debug("*  kernel: config '%s' from image at 0x%08lx\n",
-                     *fit_uname_config, kernel_addr);
-       } else if (CONFIG_IS_ENABLED(FIT) &&
-                  fit_parse_subimage(img_addr, image_load_addr, &kernel_addr,
-                                     fit_uname_kernel)) {
-               debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
-                     *fit_uname_kernel, kernel_addr);
-       } else {
-               kernel_addr = hextoul(img_addr, NULL);
-               debug("*  kernel: cmdline image address = 0x%08lx\n",
-                     kernel_addr);
-       }
-
-       return kernel_addr;
-}
-
-/**
- * genimg_get_kernel_addr() is the simple version of
- * genimg_get_kernel_addr_fit(). It ignores those return FIT strings
- */
-ulong genimg_get_kernel_addr(char * const img_addr)
-{
-       const char *fit_uname_config = NULL;
-       const char *fit_uname_kernel = NULL;
-
-       return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config,
-                                         &fit_uname_kernel);
-}
-
-/**
- * genimg_get_format - get image format type
- * @img_addr: image start address
- *
- * genimg_get_format() checks whether provided address points to a valid
- * legacy or FIT image.
- *
- * New uImage format and FDT blob are based on a libfdt. FDT blob
- * may be passed directly or embedded in a FIT image. In both situations
- * genimg_get_format() must be able to dectect libfdt header.
- *
- * returns:
- *     image format type or IMAGE_FORMAT_INVALID if no image is present
- */
-int genimg_get_format(const void *img_addr)
-{
-       if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
-               const image_header_t *hdr;
-
-               hdr = (const image_header_t *)img_addr;
-               if (image_check_magic(hdr))
-                       return IMAGE_FORMAT_LEGACY;
-       }
-       if (CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT)) {
-               if (!fdt_check_header(img_addr))
-                       return IMAGE_FORMAT_FIT;
-       }
-       if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE) &&
-           !android_image_check_header(img_addr))
-               return IMAGE_FORMAT_ANDROID;
-
-       return IMAGE_FORMAT_INVALID;
-}
-
-/**
- * fit_has_config - check if there is a valid FIT configuration
- * @images: pointer to the bootm command headers structure
- *
- * fit_has_config() checks if there is a FIT configuration in use
- * (if FTI support is present).
- *
- * returns:
- *     0, no FIT support or no configuration found
- *     1, configuration found
- */
-int genimg_has_config(bootm_headers_t *images)
-{
-       if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg)
-               return 1;
-
-       return 0;
-}
-
-/**
- * select_ramdisk() - Select and locate the ramdisk to use
- *
- * @images: pointer to the bootm images structure
- * @select: name of ramdisk to select, or NULL for any
- * @arch: expected ramdisk architecture
- * @rd_datap: pointer to a ulong variable, will hold ramdisk pointer
- * @rd_lenp: pointer to a ulong variable, will hold ramdisk length
- * @return 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported),
- *     other -ve value on other error
- */
-static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
-                         ulong *rd_datap, ulong *rd_lenp)
-{
-       ulong rd_addr = 0;
-       char *buf;
-       const char *fit_uname_config = images->fit_uname_cfg;
-       const char *fit_uname_ramdisk = NULL;
-       bool processed;
-       int rd_noffset;
-
-       if (select) {
-               ulong default_addr;
-               bool done = true;
-
-               if (CONFIG_IS_ENABLED(FIT)) {
-                       /*
-                        * If the init ramdisk comes from the FIT image and
-                        * the FIT image address is omitted in the command
-                        * line argument, try to use os FIT image address or
-                        * default load address.
-                        */
-                       if (images->fit_uname_os)
-                               default_addr = (ulong)images->fit_hdr_os;
-                       else
-                               default_addr = image_load_addr;
-
-                       if (fit_parse_conf(select, default_addr, &rd_addr,
-                                          &fit_uname_config)) {
-                               debug("*  ramdisk: config '%s' from image at 0x%08lx\n",
-                                     fit_uname_config, rd_addr);
-                       } else if (fit_parse_subimage(select, default_addr,
-                                                     &rd_addr,
-                                                     &fit_uname_ramdisk)) {
-                               debug("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
-                                     fit_uname_ramdisk, rd_addr);
-                       } else {
-                               done = false;
-                       }
-               }
-               if (!done) {
-                       rd_addr = hextoul(select, NULL);
-                       debug("*  ramdisk: cmdline image address = 0x%08lx\n",
-                             rd_addr);
-               }
-       } else if (CONFIG_IS_ENABLED(FIT)) {
-               /* use FIT configuration provided in first bootm
-                * command argument. If the property is not defined,
-                * quit silently (with -ENOPKG  )
-                */
-               rd_addr = map_to_sysmem(images->fit_hdr_os);
-               rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP,
-                                                     rd_addr);
-               if (rd_noffset == -ENOENT)
-                       return -ENOPKG;
-               else if (rd_noffset < 0)
-                       return rd_noffset;
-       }
-
-       /*
-        * Check if there is an initrd image at the
-        * address provided in the second bootm argument
-        * check image type, for FIT images get FIT node.
-        */
-       buf = map_sysmem(rd_addr, 0);
-       processed = false;
-       switch (genimg_get_format(buf)) {
-       case IMAGE_FORMAT_LEGACY:
-               if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
-                       const image_header_t *rd_hdr;
-
-                       printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n",
-                              rd_addr);
-
-                       bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
-                       rd_hdr = image_get_ramdisk(rd_addr, arch, images->verify);
-                       if (!rd_hdr)
-                               return -ENOENT;
-
-                       *rd_datap = image_get_data(rd_hdr);
-                       *rd_lenp = image_get_data_size(rd_hdr);
-                       processed = true;
-               }
-               break;
-       case IMAGE_FORMAT_FIT:
-               if (CONFIG_IS_ENABLED(FIT)) {
-                       rd_noffset = fit_image_load(images, rd_addr,
-                                                   &fit_uname_ramdisk,
-                                                   &fit_uname_config, arch,
-                                                   IH_TYPE_RAMDISK,
-                                                   BOOTSTAGE_ID_FIT_RD_START,
-                                                   FIT_LOAD_OPTIONAL_NON_ZERO,
-                                                   rd_datap, rd_lenp);
-                       if (rd_noffset < 0)
-                               return rd_noffset;
-
-                       images->fit_hdr_rd = map_sysmem(rd_addr, 0);
-                       images->fit_uname_rd = fit_uname_ramdisk;
-                       images->fit_noffset_rd = rd_noffset;
-                       processed = true;
-               }
-               break;
-       case IMAGE_FORMAT_ANDROID:
-               if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
-                       android_image_get_ramdisk((void *)images->os.start,
-                                                 rd_datap, rd_lenp);
-                       processed = true;
-               }
-               break;
-       }
-
-       if (!processed) {
-               if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
-                       char *end = NULL;
-
-                       if (select)
-                               end = strchr(select, ':');
-                       if (end) {
-                               *rd_lenp = hextoul(++end, NULL);
-                               *rd_datap = rd_addr;
-                               processed = true;
-                       }
-               }
-
-               if (!processed) {
-                       puts("Wrong Ramdisk Image Format\n");
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * boot_get_ramdisk - main ramdisk handling routine
- * @argc: command argument count
- * @argv: command argument list
- * @images: pointer to the bootm images structure
- * @arch: expected ramdisk architecture
- * @rd_start: pointer to a ulong variable, will hold ramdisk start address
- * @rd_end: pointer to a ulong variable, will hold ramdisk end
- *
- * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
- * Currently supported are the following ramdisk sources:
- *      - multicomponent kernel/ramdisk image,
- *      - commandline provided address of decicated ramdisk image.
- *
- * returns:
- *     0, if ramdisk image was found and valid, or skiped
- *     rd_start and rd_end are set to ramdisk start/end addresses if
- *     ramdisk image is found and valid
- *
- *     1, if ramdisk image is found but corrupted, or invalid
- *     rd_start and rd_end are set to 0 if no ramdisk exists
- */
-int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images,
-                    u8 arch, ulong *rd_start, ulong *rd_end)
-{
-       ulong rd_data, rd_len;
-       const char *select = NULL;
-
-       *rd_start = 0;
-       *rd_end = 0;
-
-       if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
-               char *buf;
-
-               /* Look for an Android boot image */
-               buf = map_sysmem(images->os.start, 0);
-               if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID)
-                       select = (argc == 0) ? env_get("loadaddr") : argv[0];
-       }
-
-       if (argc >= 2)
-               select = argv[1];
-
-       /*
-        * Look for a '-' which indicates to ignore the
-        * ramdisk argument
-        */
-       if (select && strcmp(select, "-") ==  0) {
-               debug("## Skipping init Ramdisk\n");
-               rd_len = 0;
-               rd_data = 0;
-       } else if (select || genimg_has_config(images)) {
-               int ret;
-
-               ret = select_ramdisk(images, select, arch, &rd_data, &rd_len);
-               if (ret == -ENOPKG)
-                       return 0;
-               else if (ret)
-                       return ret;
-       } else if (images->legacy_hdr_valid &&
-                       image_check_type(&images->legacy_hdr_os_copy,
-                                        IH_TYPE_MULTI)) {
-               /*
-                * Now check if we have a legacy mult-component image,
-                * get second entry data start address and len.
-                */
-               bootstage_mark(BOOTSTAGE_ID_RAMDISK);
-               printf("## Loading init Ramdisk from multi component Legacy Image at %08lx ...\n",
-                      (ulong)images->legacy_hdr_os);
-
-               image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
-       } else {
-               /*
-                * no initrd image
-                */
-               bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK);
-               rd_len = 0;
-               rd_data = 0;
-       }
-
-       if (!rd_data) {
-               debug("## No init Ramdisk\n");
-       } else {
-               *rd_start = rd_data;
-               *rd_end = rd_data + rd_len;
-       }
-       debug("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
-             *rd_start, *rd_end);
-
-       return 0;
-}
-
-/**
- * boot_ramdisk_high - relocate init ramdisk
- * @lmb: pointer to lmb handle, will be used for memory mgmt
- * @rd_data: ramdisk data start address
- * @rd_len: ramdisk data length
- * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
- *      start address (after possible relocation)
- * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
- *      end address (after possible relocation)
- *
- * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
- * variable and if requested ramdisk data is moved to a specified location.
- *
- * Initrd_start and initrd_end are set to final (after relocation) ramdisk
- * start/end addresses if ramdisk image start and len were provided,
- * otherwise set initrd_start and initrd_end set to zeros.
- *
- * returns:
- *      0 - success
- *     -1 - failure
- */
-int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
-                     ulong *initrd_start, ulong *initrd_end)
-{
-       char    *s;
-       ulong   initrd_high;
-       int     initrd_copy_to_ram = 1;
-
-       s = env_get("initrd_high");
-       if (s) {
-               /* a value of "no" or a similar string will act like 0,
-                * turning the "load high" feature off. This is intentional.
-                */
-               initrd_high = hextoul(s, NULL);
-               if (initrd_high == ~0)
-                       initrd_copy_to_ram = 0;
-       } else {
-               initrd_high = env_get_bootm_mapsize() + env_get_bootm_low();
-       }
-
-       debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
-             initrd_high, initrd_copy_to_ram);
-
-       if (rd_data) {
-               if (!initrd_copy_to_ram) {      /* zero-copy ramdisk support */
-                       debug("   in-place initrd\n");
-                       *initrd_start = rd_data;
-                       *initrd_end = rd_data + rd_len;
-                       lmb_reserve(lmb, rd_data, rd_len);
-               } else {
-                       if (initrd_high)
-                               *initrd_start = (ulong)lmb_alloc_base(lmb,
-                                               rd_len, 0x1000, initrd_high);
-                       else
-                               *initrd_start = (ulong)lmb_alloc(lmb, rd_len,
-                                                                0x1000);
-
-                       if (*initrd_start == 0) {
-                               puts("ramdisk - allocation error\n");
-                               goto error;
-                       }
-                       bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
-
-                       *initrd_end = *initrd_start + rd_len;
-                       printf("   Loading Ramdisk to %08lx, end %08lx ... ",
-                              *initrd_start, *initrd_end);
-
-                       memmove_wd((void *)*initrd_start,
-                                  (void *)rd_data, rd_len, CHUNKSZ);
-
-                       /*
-                        * Ensure the image is flushed to memory to handle
-                        * AMP boot scenarios in which we might not be
-                        * HW cache coherent
-                        */
-                       if (IS_ENABLED(CONFIG_MP)) {
-                               flush_cache((unsigned long)*initrd_start,
-                                           ALIGN(rd_len, ARCH_DMA_MINALIGN));
-                       }
-                       puts("OK\n");
-               }
-       } else {
-               *initrd_start = 0;
-               *initrd_end = 0;
-       }
-       debug("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
-             *initrd_start, *initrd_end);
-
-       return 0;
-
-error:
-       return -1;
-}
-
-int boot_get_setup(bootm_headers_t *images, u8 arch,
-                  ulong *setup_start, ulong *setup_len)
-{
-       if (!CONFIG_IS_ENABLED(FIT))
-               return -ENOENT;
-
-       return boot_get_setup_fit(images, arch, setup_start, setup_len);
-}
-
-int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images,
-                 u8 arch, const ulong *ld_start, ulong * const ld_len)
-{
-       ulong tmp_img_addr, img_data, img_len;
-       void *buf;
-       int conf_noffset;
-       int fit_img_result;
-       const char *uname, *name;
-       int err;
-       int devnum = 0; /* TODO support multi fpga platforms */
-
-       if (!IS_ENABLED(CONFIG_FPGA))
-               return -ENOSYS;
-
-       /* Check to see if the images struct has a FIT configuration */
-       if (!genimg_has_config(images)) {
-               debug("## FIT configuration was not specified\n");
-               return 0;
-       }
-
-       /*
-        * Obtain the os FIT header from the images struct
-        */
-       tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
-       buf = map_sysmem(tmp_img_addr, 0);
-       /*
-        * Check image type. For FIT images get FIT node
-        * and attempt to locate a generic binary.
-        */
-       switch (genimg_get_format(buf)) {
-       case IMAGE_FORMAT_FIT:
-               conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
-
-               uname = fdt_stringlist_get(buf, conf_noffset, FIT_FPGA_PROP, 0,
-                                          NULL);
-               if (!uname) {
-                       debug("## FPGA image is not specified\n");
-                       return 0;
-               }
-               fit_img_result = fit_image_load(images,
-                                               tmp_img_addr,
-                                               (const char **)&uname,
-                                               &images->fit_uname_cfg,
-                                               arch,
-                                               IH_TYPE_FPGA,
-                                               BOOTSTAGE_ID_FPGA_INIT,
-                                               FIT_LOAD_OPTIONAL_NON_ZERO,
-                                               &img_data, &img_len);
-
-               debug("FPGA image (%s) loaded to 0x%lx/size 0x%lx\n",
-                     uname, img_data, img_len);
-
-               if (fit_img_result < 0) {
-                       /* Something went wrong! */
-                       return fit_img_result;
-               }
-
-               if (!fpga_is_partial_data(devnum, img_len)) {
-                       name = "full";
-                       err = fpga_loadbitstream(devnum, (char *)img_data,
-                                                img_len, BIT_FULL);
-                       if (err)
-                               err = fpga_load(devnum, (const void *)img_data,
-                                               img_len, BIT_FULL);
-               } else {
-                       name = "partial";
-                       err = fpga_loadbitstream(devnum, (char *)img_data,
-                                                img_len, BIT_PARTIAL);
-                       if (err)
-                               err = fpga_load(devnum, (const void *)img_data,
-                                               img_len, BIT_PARTIAL);
-               }
-
-               if (err)
-                       return err;
-
-               printf("   Programming %s bitstream... OK\n", name);
-               break;
-       default:
-               printf("The given image format is not supported (corrupt?)\n");
-               return 1;
-       }
-
-       return 0;
-}
-
-static void fit_loadable_process(u8 img_type,
-                                ulong img_data,
-                                ulong img_len)
-{
-       int i;
-       const unsigned int count =
-                       ll_entry_count(struct fit_loadable_tbl, fit_loadable);
-       struct fit_loadable_tbl *fit_loadable_handler =
-                       ll_entry_start(struct fit_loadable_tbl, fit_loadable);
-       /* For each loadable handler */
-       for (i = 0; i < count; i++, fit_loadable_handler++)
-               /* matching this type */
-               if (fit_loadable_handler->type == img_type)
-                       /* call that handler with this image data */
-                       fit_loadable_handler->handler(img_data, img_len);
-}
-
-int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images,
-                     u8 arch, const ulong *ld_start, ulong * const ld_len)
-{
-       /*
-        * These variables are used to hold the current image location
-        * in system memory.
-        */
-       ulong tmp_img_addr;
-       /*
-        * These two variables are requirements for fit_image_load, but
-        * their values are not used
-        */
-       ulong img_data, img_len;
-       void *buf;
-       int loadables_index;
-       int conf_noffset;
-       int fit_img_result;
-       const char *uname;
-       u8 img_type;
-
-       /* Check to see if the images struct has a FIT configuration */
-       if (!genimg_has_config(images)) {
-               debug("## FIT configuration was not specified\n");
-               return 0;
-       }
-
-       /*
-        * Obtain the os FIT header from the images struct
-        */
-       tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
-       buf = map_sysmem(tmp_img_addr, 0);
-       /*
-        * Check image type. For FIT images get FIT node
-        * and attempt to locate a generic binary.
-        */
-       switch (genimg_get_format(buf)) {
-       case IMAGE_FORMAT_FIT:
-               conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
-
-               for (loadables_index = 0;
-                    uname = fdt_stringlist_get(buf, conf_noffset,
-                                               FIT_LOADABLE_PROP,
-                                               loadables_index, NULL), uname;
-                    loadables_index++) {
-                       fit_img_result = fit_image_load(images, tmp_img_addr,
-                                                       &uname,
-                                                       &images->fit_uname_cfg,
-                                                       arch, IH_TYPE_LOADABLE,
-                                                       BOOTSTAGE_ID_FIT_LOADABLE_START,
-                                                       FIT_LOAD_OPTIONAL_NON_ZERO,
-                                                       &img_data, &img_len);
-                       if (fit_img_result < 0) {
-                               /* Something went wrong! */
-                               return fit_img_result;
-                       }
-
-                       fit_img_result = fit_image_get_node(buf, uname);
-                       if (fit_img_result < 0) {
-                               /* Something went wrong! */
-                               return fit_img_result;
-                       }
-                       fit_img_result = fit_image_get_type(buf,
-                                                           fit_img_result,
-                                                           &img_type);
-                       if (fit_img_result < 0) {
-                               /* Something went wrong! */
-                               return fit_img_result;
-                       }
-
-                       fit_loadable_process(img_type, img_data, img_len);
-               }
-               break;
-       default:
-               printf("The given image format is not supported (corrupt?)\n");
-               return 1;
-       }
-
-       return 0;
-}
-
-/**
- * boot_get_cmdline - allocate and initialize kernel cmdline
- * @lmb: pointer to lmb handle, will be used for memory mgmt
- * @cmd_start: pointer to a ulong variable, will hold cmdline start
- * @cmd_end: pointer to a ulong variable, will hold cmdline end
- *
- * boot_get_cmdline() allocates space for kernel command line below
- * BOOTMAPSZ + env_get_bootm_low() address. If "bootargs" U-Boot environment
- * variable is present its contents is copied to allocated kernel
- * command line.
- *
- * returns:
- *      0 - success
- *     -1 - failure
- */
-int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
-{
-       char *cmdline;
-       char *s;
-
-       cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
-                               env_get_bootm_mapsize() + env_get_bootm_low());
-       if (!cmdline)
-               return -1;
-
-       s = env_get("bootargs");
-       if (!s)
-               s = "";
-
-       strcpy(cmdline, s);
-
-       *cmd_start = (ulong)cmdline;
-       *cmd_end = *cmd_start + strlen(cmdline);
-
-       debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
-
-       return 0;
-}
-
-/**
- * boot_get_kbd - allocate and initialize kernel copy of board info
- * @lmb: pointer to lmb handle, will be used for memory mgmt
- * @kbd: double pointer to board info data
- *
- * boot_get_kbd() allocates space for kernel copy of board info data below
- * BOOTMAPSZ + env_get_bootm_low() address and kernel board info is initialized
- * with the current u-boot board info data.
- *
- * returns:
- *      0 - success
- *     -1 - failure
- */
-int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd)
-{
-       *kbd = (struct bd_info *)(ulong)lmb_alloc_base(lmb,
-                                                      sizeof(struct bd_info),
-                                                      0xf,
-                                                      env_get_bootm_mapsize() +
-                                                      env_get_bootm_low());
-       if (!*kbd)
-               return -1;
-
-       **kbd = *gd->bd;
-
-       debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
-
-#if defined(DEBUG)
-       if (IS_ENABLED(CONFIG_CMD_BDI))
-               do_bdinfo(NULL, 0, 0, NULL);
-#endif
-
-       return 0;
-}
-
-int image_setup_linux(bootm_headers_t *images)
-{
-       ulong of_size = images->ft_len;
-       char **of_flat_tree = &images->ft_addr;
-       struct lmb *lmb = &images->lmb;
-       int ret;
-
-       if (CONFIG_IS_ENABLED(OF_LIBFDT))
-               boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
-
-       if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) {
-               ret = boot_get_cmdline(lmb, &images->cmdline_start,
-                                      &images->cmdline_end);
-               if (ret) {
-                       puts("ERROR with allocation of cmdline\n");
-                       return ret;
-               }
-       }
-
-       if (CONFIG_IS_ENABLED(OF_LIBFDT)) {
-               ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
-               if (ret)
-                       return ret;
-       }
-
-       if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) {
-               ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-void genimg_print_size(uint32_t size)
-{
-       printf("%d Bytes = ", size);
-       print_size(size, "\n");
-}
-
-void genimg_print_time(time_t timestamp)
-{
-       struct rtc_time tm;
-
-       rtc_to_tm(timestamp, &tm);
-       printf("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
-              tm.tm_year, tm.tm_mon, tm.tm_mday,
-              tm.tm_hour, tm.tm_min, tm.tm_sec);
-}
diff --git a/common/image-cipher.c b/common/image-cipher.c
deleted file mode 100644 (file)
index b906148..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2019, Softathome
- */
-
-#ifdef USE_HOSTCC
-#include "mkimage.h"
-#include <time.h>
-#else
-#include <common.h>
-#include <malloc.h>
-#include <asm/global_data.h>
-DECLARE_GLOBAL_DATA_PTR;
-#endif /* !USE_HOSdTCC*/
-#include <image.h>
-#include <uboot_aes.h>
-#include <u-boot/aes.h>
-
-struct cipher_algo cipher_algos[] = {
-       {
-               .name = "aes128",
-               .key_len = AES128_KEY_LENGTH,
-               .iv_len  = AES_BLOCK_LENGTH,
-#if IMAGE_ENABLE_ENCRYPT
-               .calculate_type = EVP_aes_128_cbc,
-#endif
-               .encrypt = image_aes_encrypt,
-               .decrypt = image_aes_decrypt,
-               .add_cipher_data = image_aes_add_cipher_data
-       },
-       {
-               .name = "aes192",
-               .key_len = AES192_KEY_LENGTH,
-               .iv_len  = AES_BLOCK_LENGTH,
-#if IMAGE_ENABLE_ENCRYPT
-               .calculate_type = EVP_aes_192_cbc,
-#endif
-               .encrypt = image_aes_encrypt,
-               .decrypt = image_aes_decrypt,
-               .add_cipher_data = image_aes_add_cipher_data
-       },
-       {
-               .name = "aes256",
-               .key_len = AES256_KEY_LENGTH,
-               .iv_len  = AES_BLOCK_LENGTH,
-#if IMAGE_ENABLE_ENCRYPT
-               .calculate_type = EVP_aes_256_cbc,
-#endif
-               .encrypt = image_aes_encrypt,
-               .decrypt = image_aes_decrypt,
-               .add_cipher_data = image_aes_add_cipher_data
-       }
-};
-
-struct cipher_algo *image_get_cipher_algo(const char *full_name)
-{
-       int i;
-       const char *name;
-
-       for (i = 0; i < ARRAY_SIZE(cipher_algos); i++) {
-               name = cipher_algos[i].name;
-               if (!strncmp(name, full_name, strlen(name)))
-                       return &cipher_algos[i];
-       }
-
-       return NULL;
-}
-
-static int fit_image_setup_decrypt(struct image_cipher_info *info,
-                                  const void *fit, int image_noffset,
-                                  int cipher_noffset)
-{
-       const void *fdt = gd_fdt_blob();
-       const char *node_name;
-       char node_path[128];
-       int noffset;
-       char *algo_name;
-       int ret;
-
-       node_name = fit_get_name(fit, image_noffset, NULL);
-       if (!node_name) {
-               printf("Can't get node name\n");
-               return -1;
-       }
-
-       if (fit_image_cipher_get_algo(fit, cipher_noffset, &algo_name)) {
-               printf("Can't get algo name for cipher '%s' in image '%s'\n",
-                      node_name, node_name);
-               return -1;
-       }
-
-       info->keyname = fdt_getprop(fit, cipher_noffset, FIT_KEY_HINT, NULL);
-       if (!info->keyname) {
-               printf("Can't get key name\n");
-               return -1;
-       }
-
-       info->iv = fdt_getprop(fit, cipher_noffset, "iv", NULL);
-       info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL);
-
-       if (!info->iv && !info->ivname) {
-               printf("Can't get IV or IV name\n");
-               return -1;
-       }
-
-       info->fit = fit;
-       info->node_noffset = image_noffset;
-       info->name = algo_name;
-       info->cipher = image_get_cipher_algo(algo_name);
-       if (!info->cipher) {
-               printf("Can't get cipher\n");
-               return -1;
-       }
-
-       ret = fit_image_get_data_size_unciphered(fit, image_noffset,
-                                                &info->size_unciphered);
-       if (ret) {
-               printf("Can't get size of unciphered data\n");
-               return -1;
-       }
-
-       /*
-        * Search the cipher node in the u-boot fdt
-        * the path should be: /cipher/key-<algo>-<key>-<iv>
-        */
-       if (info->ivname)
-               snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s",
-                        FIT_CIPHER_NODENAME, algo_name, info->keyname, info->ivname);
-       else
-               snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s",
-                        FIT_CIPHER_NODENAME, algo_name, info->keyname);
-
-       noffset = fdt_path_offset(fdt, node_path);
-       if (noffset < 0) {
-               printf("Can't found cipher node offset\n");
-               return -1;
-       }
-
-       /* read key */
-       info->key = fdt_getprop(fdt, noffset, "key", NULL);
-       if (!info->key) {
-               printf("Can't get key in cipher node '%s'\n", node_path);
-               return -1;
-       }
-
-       /* read iv */
-       if (!info->iv) {
-               info->iv = fdt_getprop(fdt, noffset, "iv", NULL);
-               if (!info->iv) {
-                       printf("Can't get IV in cipher node '%s'\n", node_path);
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-int fit_image_decrypt_data(const void *fit,
-                          int image_noffset, int cipher_noffset,
-                          const void *data_ciphered, size_t size_ciphered,
-                          void **data_unciphered, size_t *size_unciphered)
-{
-       struct image_cipher_info info;
-       int ret;
-
-       ret = fit_image_setup_decrypt(&info, fit, image_noffset,
-                                     cipher_noffset);
-       if (ret < 0)
-               goto out;
-
-       ret = info.cipher->decrypt(&info, data_ciphered, size_ciphered,
-                                  data_unciphered, size_unciphered);
-
- out:
-       return ret;
-}
diff --git a/common/image-fdt.c b/common/image-fdt.c
deleted file mode 100644 (file)
index 7aad6d5..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2013, Google Inc.
- *
- * (C) Copyright 2008 Semihalf
- *
- * (C) Copyright 2000-2006
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#include <common.h>
-#include <fdt_support.h>
-#include <fdtdec.h>
-#include <env.h>
-#include <errno.h>
-#include <image.h>
-#include <lmb.h>
-#include <log.h>
-#include <malloc.h>
-#include <asm/global_data.h>
-#include <linux/libfdt.h>
-#include <mapmem.h>
-#include <asm/io.h>
-#include <tee/optee.h>
-
-#ifndef CONFIG_SYS_FDT_PAD
-#define CONFIG_SYS_FDT_PAD 0x3000
-#endif
-
-/* adding a ramdisk needs 0x44 bytes in version 2008.10 */
-#define FDT_RAMDISK_OVERHEAD   0x80
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static void fdt_error(const char *msg)
-{
-       puts("ERROR: ");
-       puts(msg);
-       puts(" - must RESET the board to recover.\n");
-}
-
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
-static const image_header_t *image_get_fdt(ulong fdt_addr)
-{
-       const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0);
-
-       image_print_contents(fdt_hdr);
-
-       puts("   Verifying Checksum ... ");
-       if (!image_check_hcrc(fdt_hdr)) {
-               fdt_error("fdt header checksum invalid");
-               return NULL;
-       }
-
-       if (!image_check_dcrc(fdt_hdr)) {
-               fdt_error("fdt checksum invalid");
-               return NULL;
-       }
-       puts("OK\n");
-
-       if (!image_check_type(fdt_hdr, IH_TYPE_FLATDT)) {
-               fdt_error("uImage is not a fdt");
-               return NULL;
-       }
-       if (image_get_comp(fdt_hdr) != IH_COMP_NONE) {
-               fdt_error("uImage is compressed");
-               return NULL;
-       }
-       if (fdt_check_header((void *)image_get_data(fdt_hdr)) != 0) {
-               fdt_error("uImage data is not a fdt");
-               return NULL;
-       }
-       return fdt_hdr;
-}
-#endif
-
-static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
-                                   uint64_t size, enum lmb_flags flags)
-{
-       long ret;
-
-       ret = lmb_reserve_flags(lmb, addr, size, flags);
-       if (ret >= 0) {
-               debug("   reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
-                     (unsigned long long)addr,
-                     (unsigned long long)size, flags);
-       } else {
-               puts("ERROR: reserving fdt memory region failed ");
-               printf("(addr=%llx size=%llx flags=%x)\n",
-                      (unsigned long long)addr,
-                      (unsigned long long)size, flags);
-       }
-}
-
-/**
- * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
- * sections as unusable
- * @lmb: pointer to lmb handle, will be used for memory mgmt
- * @fdt_blob: pointer to fdt blob base address
- *
- * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block.
- * Adding the memreserve regions prevents u-boot from using them to store the
- * initrd or the fdt blob.
- */
-void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
-{
-       uint64_t addr, size;
-       int i, total, ret;
-       int nodeoffset, subnode;
-       struct fdt_resource res;
-       enum lmb_flags flags;
-
-       if (fdt_check_header(fdt_blob) != 0)
-               return;
-
-       /* process memreserve sections */
-       total = fdt_num_mem_rsv(fdt_blob);
-       for (i = 0; i < total; i++) {
-               if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
-                       continue;
-               boot_fdt_reserve_region(lmb, addr, size, LMB_NONE);
-       }
-
-       /* process reserved-memory */
-       nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory");
-       if (nodeoffset >= 0) {
-               subnode = fdt_first_subnode(fdt_blob, nodeoffset);
-               while (subnode >= 0) {
-                       /* check if this subnode has a reg property */
-                       ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
-                                              &res);
-                       if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) {
-                               flags = LMB_NONE;
-                               if (fdtdec_get_bool(fdt_blob, subnode,
-                                                   "no-map"))
-                                       flags = LMB_NOMAP;
-                               addr = res.start;
-                               size = res.end - res.start + 1;
-                               boot_fdt_reserve_region(lmb, addr, size, flags);
-                       }
-
-                       subnode = fdt_next_subnode(fdt_blob, subnode);
-               }
-       }
-}
-
-/**
- * boot_relocate_fdt - relocate flat device tree
- * @lmb: pointer to lmb handle, will be used for memory mgmt
- * @of_flat_tree: pointer to a char* variable, will hold fdt start address
- * @of_size: pointer to a ulong variable, will hold fdt length
- *
- * boot_relocate_fdt() allocates a region of memory within the bootmap and
- * relocates the of_flat_tree into that region, even if the fdt is already in
- * the bootmap.  It also expands the size of the fdt by CONFIG_SYS_FDT_PAD
- * bytes.
- *
- * of_flat_tree and of_size are set to final (after relocation) values
- *
- * returns:
- *      0 - success
- *      1 - failure
- */
-int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
-{
-       void    *fdt_blob = *of_flat_tree;
-       void    *of_start = NULL;
-       char    *fdt_high;
-       ulong   of_len = 0;
-       int     err;
-       int     disable_relocation = 0;
-
-       /* nothing to do */
-       if (*of_size == 0)
-               return 0;
-
-       if (fdt_check_header(fdt_blob) != 0) {
-               fdt_error("image is not a fdt");
-               goto error;
-       }
-
-       /* position on a 4K boundary before the alloc_current */
-       /* Pad the FDT by a specified amount */
-       of_len = *of_size + CONFIG_SYS_FDT_PAD;
-
-       /* If fdt_high is set use it to select the relocation address */
-       fdt_high = env_get("fdt_high");
-       if (fdt_high) {
-               void *desired_addr = (void *)hextoul(fdt_high, NULL);
-
-               if (((ulong) desired_addr) == ~0UL) {
-                       /* All ones means use fdt in place */
-                       of_start = fdt_blob;
-                       lmb_reserve(lmb, (ulong)of_start, of_len);
-                       disable_relocation = 1;
-               } else if (desired_addr) {
-                       of_start =
-                           (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
-                                                          (ulong)desired_addr);
-                       if (of_start == NULL) {
-                               puts("Failed using fdt_high value for Device Tree");
-                               goto error;
-                       }
-               } else {
-                       of_start =
-                           (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000);
-               }
-       } else {
-               of_start =
-                   (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
-                                                  env_get_bootm_mapsize()
-                                                  + env_get_bootm_low());
-       }
-
-       if (of_start == NULL) {
-               puts("device tree - allocation error\n");
-               goto error;
-       }
-
-       if (disable_relocation) {
-               /*
-                * We assume there is space after the existing fdt to use
-                * for padding
-                */
-               fdt_set_totalsize(of_start, of_len);
-               printf("   Using Device Tree in place at %p, end %p\n",
-                      of_start, of_start + of_len - 1);
-       } else {
-               debug("## device tree at %p ... %p (len=%ld [0x%lX])\n",
-                     fdt_blob, fdt_blob + *of_size - 1, of_len, of_len);
-
-               printf("   Loading Device Tree to %p, end %p ... ",
-                      of_start, of_start + of_len - 1);
-
-               err = fdt_open_into(fdt_blob, of_start, of_len);
-               if (err != 0) {
-                       fdt_error("fdt move failed");
-                       goto error;
-               }
-               puts("OK\n");
-       }
-
-       *of_flat_tree = of_start;
-       *of_size = of_len;
-
-       if (CONFIG_IS_ENABLED(CMD_FDT))
-               set_working_fdt_addr(map_to_sysmem(*of_flat_tree));
-       return 0;
-
-error:
-       return 1;
-}
-
-/**
- * select_fdt() - Select and locate the FDT to use
- *
- * @images: pointer to the bootm images structure
- * @select: name of FDT to select, or NULL for any
- * @arch: expected FDT architecture
- * @fdt_addrp: pointer to a ulong variable, will hold FDT pointer
- * @return 0 if OK, -ENOPKG if no FDT (but an error should not be reported),
- *     other -ve value on other error
- */
-
-static int select_fdt(bootm_headers_t *images, const char *select, u8 arch,
-                     ulong *fdt_addrp)
-{
-       const char *buf;
-       ulong fdt_addr;
-
-#if CONFIG_IS_ENABLED(FIT)
-       const char *fit_uname_config = images->fit_uname_cfg;
-       const char *fit_uname_fdt = NULL;
-       ulong default_addr;
-       int fdt_noffset;
-
-       if (select) {
-                       /*
-                        * If the FDT blob comes from the FIT image and the
-                        * FIT image address is omitted in the command line
-                        * argument, try to use ramdisk or os FIT image
-                        * address or default load address.
-                        */
-                       if (images->fit_uname_rd)
-                               default_addr = (ulong)images->fit_hdr_rd;
-                       else if (images->fit_uname_os)
-                               default_addr = (ulong)images->fit_hdr_os;
-                       else
-                               default_addr = image_load_addr;
-
-                       if (fit_parse_conf(select, default_addr, &fdt_addr,
-                                          &fit_uname_config)) {
-                               debug("*  fdt: config '%s' from image at 0x%08lx\n",
-                                     fit_uname_config, fdt_addr);
-                       } else if (fit_parse_subimage(select, default_addr, &fdt_addr,
-                                  &fit_uname_fdt)) {
-                               debug("*  fdt: subimage '%s' from image at 0x%08lx\n",
-                                     fit_uname_fdt, fdt_addr);
-                       } else
-#endif
-               {
-                       fdt_addr = hextoul(select, NULL);
-                       debug("*  fdt: cmdline image address = 0x%08lx\n",
-                             fdt_addr);
-               }
-#if CONFIG_IS_ENABLED(FIT)
-       } else {
-               /* use FIT configuration provided in first bootm
-                * command argument
-                */
-               fdt_addr = map_to_sysmem(images->fit_hdr_os);
-               fdt_noffset = fit_get_node_from_config(images, FIT_FDT_PROP,
-                                                      fdt_addr);
-               if (fdt_noffset == -ENOENT)
-                       return -ENOPKG;
-               else if (fdt_noffset < 0)
-                       return fdt_noffset;
-       }
-#endif
-       debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",
-             fdt_addr);
-
-       /*
-        * Check if there is an FDT image at the
-        * address provided in the second bootm argument
-        * check image type, for FIT images get a FIT node.
-        */
-       buf = map_sysmem(fdt_addr, 0);
-       switch (genimg_get_format(buf)) {
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
-       case IMAGE_FORMAT_LEGACY: {
-                       const image_header_t *fdt_hdr;
-                       ulong load, load_end;
-                       ulong image_start, image_data, image_end;
-
-                       /* verify fdt_addr points to a valid image header */
-                       printf("## Flattened Device Tree from Legacy Image at %08lx\n",
-                              fdt_addr);
-                       fdt_hdr = image_get_fdt(fdt_addr);
-                       if (!fdt_hdr)
-                               return -ENOPKG;
-
-                       /*
-                        * move image data to the load address,
-                        * make sure we don't overwrite initial image
-                        */
-                       image_start = (ulong)fdt_hdr;
-                       image_data = (ulong)image_get_data(fdt_hdr);
-                       image_end = image_get_image_end(fdt_hdr);
-
-                       load = image_get_load(fdt_hdr);
-                       load_end = load + image_get_data_size(fdt_hdr);
-
-                       if (load == image_start ||
-                           load == image_data) {
-                               fdt_addr = load;
-                               break;
-                       }
-
-                       if ((load < image_end) && (load_end > image_start)) {
-                               fdt_error("fdt overwritten");
-                               return -EFAULT;
-                       }
-
-                       debug("   Loading FDT from 0x%08lx to 0x%08lx\n",
-                             image_data, load);
-
-                       memmove((void *)load,
-                               (void *)image_data,
-                               image_get_data_size(fdt_hdr));
-
-                       fdt_addr = load;
-                       break;
-               }
-#endif
-       case IMAGE_FORMAT_FIT:
-               /*
-                * This case will catch both: new uImage format
-                * (libfdt based) and raw FDT blob (also libfdt
-                * based).
-                */
-#if CONFIG_IS_ENABLED(FIT)
-                       /* check FDT blob vs FIT blob */
-                       if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {
-                               ulong load, len;
-
-                               fdt_noffset = boot_get_fdt_fit(images, fdt_addr,
-                                                              &fit_uname_fdt,
-                                                              &fit_uname_config,
-                                                              arch, &load, &len);
-
-                               if (fdt_noffset < 0)
-                                       return -ENOENT;
-
-                               images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
-                               images->fit_uname_fdt = fit_uname_fdt;
-                               images->fit_noffset_fdt = fdt_noffset;
-                               fdt_addr = load;
-
-                               break;
-               } else
-#endif
-               {
-                       /*
-                        * FDT blob
-                        */
-                       debug("*  fdt: raw FDT blob\n");
-                       printf("## Flattened Device Tree blob at %08lx\n",
-                              (long)fdt_addr);
-               }
-               break;
-       default:
-               puts("ERROR: Did not find a cmdline Flattened Device Tree\n");
-               return -ENOENT;
-       }
-       *fdt_addrp = fdt_addr;
-
-       return 0;
-}
-
-/**
- * boot_get_fdt - main fdt handling routine
- * @argc: command argument count
- * @argv: command argument list
- * @arch: architecture (IH_ARCH_...)
- * @images: pointer to the bootm images structure
- * @of_flat_tree: pointer to a char* variable, will hold fdt start address
- * @of_size: pointer to a ulong variable, will hold fdt length
- *
- * boot_get_fdt() is responsible for finding a valid flat device tree image.
- * Currently supported are the following ramdisk sources:
- *      - multicomponent kernel/ramdisk image,
- *      - commandline provided address of decicated ramdisk image.
- *
- * returns:
- *     0, if fdt image was found and valid, or skipped
- *     of_flat_tree and of_size are set to fdt start address and length if
- *     fdt image is found and valid
- *
- *     1, if fdt image is found but corrupted
- *     of_flat_tree and of_size are set to 0 if no fdt exists
- */
-int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
-                bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
-{
-       ulong           img_addr;
-       ulong           fdt_addr;
-       char            *fdt_blob = NULL;
-       void            *buf;
-       const char *select = NULL;
-
-       *of_flat_tree = NULL;
-       *of_size = 0;
-
-       img_addr = (argc == 0) ? image_load_addr : hextoul(argv[0], NULL);
-       buf = map_sysmem(img_addr, 0);
-
-       if (argc > 2)
-               select = argv[2];
-       if (select || genimg_has_config(images)) {
-               int ret;
-
-               ret = select_fdt(images, select, arch, &fdt_addr);
-               if (ret == -ENOPKG)
-                       goto no_fdt;
-               else if (ret)
-                       return 1;
-               printf("   Booting using the fdt blob at %#08lx\n", fdt_addr);
-               fdt_blob = map_sysmem(fdt_addr, 0);
-       } else if (images->legacy_hdr_valid &&
-                       image_check_type(&images->legacy_hdr_os_copy,
-                                        IH_TYPE_MULTI)) {
-               ulong fdt_data, fdt_len;
-
-               /*
-                * Now check if we have a legacy multi-component image,
-                * get second entry data start address and len.
-                */
-               printf("## Flattened Device Tree from multi component Image at %08lX\n",
-                      (ulong)images->legacy_hdr_os);
-
-               image_multi_getimg(images->legacy_hdr_os, 2, &fdt_data,
-                                  &fdt_len);
-               if (fdt_len) {
-                       fdt_blob = (char *)fdt_data;
-                       printf("   Booting using the fdt at 0x%p\n", fdt_blob);
-
-                       if (fdt_check_header(fdt_blob) != 0) {
-                               fdt_error("image is not a fdt");
-                               goto error;
-                       }
-
-                       if (fdt_totalsize(fdt_blob) != fdt_len) {
-                               fdt_error("fdt size != image size");
-                               goto error;
-                       }
-               } else {
-                       debug("## No Flattened Device Tree\n");
-                       goto no_fdt;
-               }
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
-       } else if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) {
-               struct andr_img_hdr *hdr = buf;
-               ulong           fdt_data, fdt_len;
-               u32                     fdt_size, dtb_idx;
-               /*
-                * Firstly check if this android boot image has dtb field.
-                */
-               dtb_idx = (u32)env_get_ulong("adtb_idx", 10, 0);
-               if (android_image_get_dtb_by_index((ulong)hdr, dtb_idx, &fdt_addr, &fdt_size)) {
-                       fdt_blob = (char *)map_sysmem(fdt_addr, 0);
-                       if (fdt_check_header(fdt_blob))
-                               goto no_fdt;
-
-                       debug("## Using FDT in Android image dtb area with idx %u\n", dtb_idx);
-               } else if (!android_image_get_second(hdr, &fdt_data, &fdt_len) &&
-                       !fdt_check_header((char *)fdt_data)) {
-                       fdt_blob = (char *)fdt_data;
-                       if (fdt_totalsize(fdt_blob) != fdt_len)
-                               goto error;
-
-                       debug("## Using FDT in Android image second area\n");
-               } else {
-                       fdt_addr = env_get_hex("fdtaddr", 0);
-                       if (!fdt_addr)
-                               goto no_fdt;
-
-                       fdt_blob = map_sysmem(fdt_addr, 0);
-                       if (fdt_check_header(fdt_blob))
-                               goto no_fdt;
-
-                       debug("## Using FDT at ${fdtaddr}=Ox%lx\n", fdt_addr);
-               }
-#endif
-       } else {
-               debug("## No Flattened Device Tree\n");
-               goto no_fdt;
-       }
-
-       *of_flat_tree = fdt_blob;
-       *of_size = fdt_totalsize(fdt_blob);
-       debug("   of_flat_tree at 0x%08lx size 0x%08lx\n",
-             (ulong)*of_flat_tree, *of_size);
-
-       return 0;
-
-no_fdt:
-       debug("Continuing to boot without FDT\n");
-       return 0;
-error:
-       return 1;
-}
-
-/*
- * Verify the device tree.
- *
- * This function is called after all device tree fix-ups have been enacted,
- * so that the final device tree can be verified.  The definition of "verified"
- * is up to the specific implementation.  However, it generally means that the
- * addresses of some of the devices in the device tree are compared with the
- * actual addresses at which U-Boot has placed them.
- *
- * Returns 1 on success, 0 on failure.  If 0 is returned, U-Boot will halt the
- * boot process.
- */
-__weak int ft_verify_fdt(void *fdt)
-{
-       return 1;
-}
-
-__weak int arch_fixup_fdt(void *blob)
-{
-       return 0;
-}
-
-int image_setup_libfdt(bootm_headers_t *images, void *blob,
-                      int of_size, struct lmb *lmb)
-{
-       ulong *initrd_start = &images->initrd_start;
-       ulong *initrd_end = &images->initrd_end;
-       int ret = -EPERM;
-       int fdt_ret;
-
-       if (fdt_root(blob) < 0) {
-               printf("ERROR: root node setup failed\n");
-               goto err;
-       }
-       if (fdt_chosen(blob) < 0) {
-               printf("ERROR: /chosen node create failed\n");
-               goto err;
-       }
-       if (arch_fixup_fdt(blob) < 0) {
-               printf("ERROR: arch-specific fdt fixup failed\n");
-               goto err;
-       }
-
-       fdt_ret = optee_copy_fdt_nodes(blob);
-       if (fdt_ret) {
-               printf("ERROR: transfer of optee nodes to new fdt failed: %s\n",
-                      fdt_strerror(fdt_ret));
-               goto err;
-       }
-
-       /* Update ethernet nodes */
-       fdt_fixup_ethernet(blob);
-#if CONFIG_IS_ENABLED(CMD_PSTORE)
-       /* Append PStore configuration */
-       fdt_fixup_pstore(blob);
-#endif
-       if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) {
-               const char *skip_board_fixup;
-
-               skip_board_fixup = env_get("skip_board_fixup");
-               if (skip_board_fixup && ((int)simple_strtol(skip_board_fixup, NULL, 10) == 1)) {
-                       printf("skip board fdt fixup\n");
-               } else {
-                       fdt_ret = ft_board_setup(blob, gd->bd);
-                       if (fdt_ret) {
-                               printf("ERROR: board-specific fdt fixup failed: %s\n",
-                                      fdt_strerror(fdt_ret));
-                               goto err;
-                       }
-               }
-       }
-       if (IS_ENABLED(CONFIG_OF_SYSTEM_SETUP)) {
-               fdt_ret = ft_system_setup(blob, gd->bd);
-               if (fdt_ret) {
-                       printf("ERROR: system-specific fdt fixup failed: %s\n",
-                              fdt_strerror(fdt_ret));
-                       goto err;
-               }
-       }
-
-       /* Delete the old LMB reservation */
-       if (lmb)
-               lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob,
-                        (phys_size_t)fdt_totalsize(blob));
-
-       ret = fdt_shrink_to_minimum(blob, 0);
-       if (ret < 0)
-               goto err;
-       of_size = ret;
-
-       if (*initrd_start && *initrd_end) {
-               of_size += FDT_RAMDISK_OVERHEAD;
-               fdt_set_totalsize(blob, of_size);
-       }
-       /* Create a new LMB reservation */
-       if (lmb)
-               lmb_reserve(lmb, (ulong)blob, of_size);
-
-       fdt_initrd(blob, *initrd_start, *initrd_end);
-       if (!ft_verify_fdt(blob))
-               goto err;
-
-#if defined(CONFIG_ARCH_KEYSTONE)
-       if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))
-               ft_board_setup_ex(blob, gd->bd);
-#endif
-
-       return 0;
-err:
-       printf(" - must RESET the board to recover.\n\n");
-
-       return ret;
-}
diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c
deleted file mode 100644 (file)
index 63e5423..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2013, Google Inc.
- */
-
-#ifdef USE_HOSTCC
-#include "mkimage.h"
-#include <time.h>
-#else
-#include <common.h>
-#include <log.h>
-#include <malloc.h>
-#include <asm/global_data.h>
-DECLARE_GLOBAL_DATA_PTR;
-#endif /* !USE_HOSTCC*/
-#include <fdt_region.h>
-#include <image.h>
-#include <u-boot/rsa.h>
-#include <u-boot/hash-checksum.h>
-
-#define IMAGE_MAX_HASHED_NODES         100
-
-/**
- * fit_region_make_list() - Make a list of image regions
- *
- * Given a list of fdt_regions, create a list of image_regions. This is a
- * simple conversion routine since the FDT and image code use different
- * structures.
- *
- * @fit: FIT image
- * @fdt_regions: Pointer to FDT regions
- * @count: Number of FDT regions
- * @region: Pointer to image regions, which must hold @count records. If
- * region is NULL, then (except for an SPL build) the array will be
- * allocated.
- * @return: Pointer to image regions
- */
-struct image_region *fit_region_make_list(const void *fit,
-                                         struct fdt_region *fdt_regions,
-                                         int count,
-                                         struct image_region *region)
-{
-       int i;
-
-       debug("Hash regions:\n");
-       debug("%10s %10s\n", "Offset", "Size");
-
-       /*
-        * Use malloc() except in SPL (to save code size). In SPL the caller
-        * must allocate the array.
-        */
-       if (!IS_ENABLED(CONFIG_SPL_BUILD) && !region)
-               region = calloc(sizeof(*region), count);
-       if (!region)
-               return NULL;
-       for (i = 0; i < count; i++) {
-               debug("%10x %10x\n", fdt_regions[i].offset,
-                     fdt_regions[i].size);
-               region[i].data = fit + fdt_regions[i].offset;
-               region[i].size = fdt_regions[i].size;
-       }
-
-       return region;
-}
-
-static int fit_image_setup_verify(struct image_sign_info *info,
-                                 const void *fit, int noffset,
-                                 int required_keynode, char **err_msgp)
-{
-       char *algo_name;
-       const char *padding_name;
-
-       if (fdt_totalsize(fit) > CONFIG_VAL(FIT_SIGNATURE_MAX_SIZE)) {
-               *err_msgp = "Total size too large";
-               return 1;
-       }
-       if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
-               *err_msgp = "Can't get hash algo property";
-               return -1;
-       }
-
-       padding_name = fdt_getprop(fit, noffset, "padding", NULL);
-       if (!padding_name)
-               padding_name = RSA_DEFAULT_PADDING_NAME;
-
-       memset(info, '\0', sizeof(*info));
-       info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
-       info->fit = fit;
-       info->node_offset = noffset;
-       info->name = algo_name;
-       info->checksum = image_get_checksum_algo(algo_name);
-       info->crypto = image_get_crypto_algo(algo_name);
-       info->padding = image_get_padding_algo(padding_name);
-       info->fdt_blob = gd_fdt_blob();
-       info->required_keynode = required_keynode;
-       printf("%s:%s", algo_name, info->keyname);
-
-       if (!info->checksum || !info->crypto || !info->padding) {
-               *err_msgp = "Unknown signature algorithm";
-               return -1;
-       }
-
-       return 0;
-}
-
-int fit_image_check_sig(const void *fit, int noffset, const void *data,
-                       size_t size, int required_keynode, char **err_msgp)
-{
-       struct image_sign_info info;
-       struct image_region region;
-       uint8_t *fit_value;
-       int fit_value_len;
-
-       *err_msgp = NULL;
-       if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
-                                  err_msgp))
-               return -1;
-
-       if (fit_image_hash_get_value(fit, noffset, &fit_value,
-                                    &fit_value_len)) {
-               *err_msgp = "Can't get hash value property";
-               return -1;
-       }
-
-       region.data = data;
-       region.size = size;
-
-       if (info.crypto->verify(&info, &region, 1, fit_value, fit_value_len)) {
-               *err_msgp = "Verification failed";
-               return -1;
-       }
-
-       return 0;
-}
-
-static int fit_image_verify_sig(const void *fit, int image_noffset,
-                               const char *data, size_t size,
-                               const void *sig_blob, int sig_offset)
-{
-       int noffset;
-       char *err_msg = "";
-       int verified = 0;
-       int ret;
-
-       /* Process all hash subnodes of the component image node */
-       fdt_for_each_subnode(noffset, fit, image_noffset) {
-               const char *name = fit_get_name(fit, noffset, NULL);
-
-               /*
-                * We don't support this since libfdt considers names with the
-                * name root but different @ suffix to be equal
-                */
-               if (strchr(name, '@')) {
-                       err_msg = "Node name contains @";
-                       goto error;
-               }
-               if (!strncmp(name, FIT_SIG_NODENAME,
-                            strlen(FIT_SIG_NODENAME))) {
-                       ret = fit_image_check_sig(fit, noffset, data,
-                                                 size, -1, &err_msg);
-                       if (ret) {
-                               puts("- ");
-                       } else {
-                               puts("+ ");
-                               verified = 1;
-                               break;
-                       }
-               }
-       }
-
-       if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
-               err_msg = "Corrupted or truncated tree";
-               goto error;
-       }
-
-       return verified ? 0 : -EPERM;
-
-error:
-       printf(" error!\n%s for '%s' hash node in '%s' image node\n",
-              err_msg, fit_get_name(fit, noffset, NULL),
-              fit_get_name(fit, image_noffset, NULL));
-       return -1;
-}
-
-int fit_image_verify_required_sigs(const void *fit, int image_noffset,
-                                  const char *data, size_t size,
-                                  const void *sig_blob, int *no_sigsp)
-{
-       int verify_count = 0;
-       int noffset;
-       int sig_node;
-
-       /* Work out what we need to verify */
-       *no_sigsp = 1;
-       sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
-       if (sig_node < 0) {
-               debug("%s: No signature node found: %s\n", __func__,
-                     fdt_strerror(sig_node));
-               return 0;
-       }
-
-       fdt_for_each_subnode(noffset, sig_blob, sig_node) {
-               const char *required;
-               int ret;
-
-               required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
-                                      NULL);
-               if (!required || strcmp(required, "image"))
-                       continue;
-               ret = fit_image_verify_sig(fit, image_noffset, data, size,
-                                          sig_blob, noffset);
-               if (ret) {
-                       printf("Failed to verify required signature '%s'\n",
-                              fit_get_name(sig_blob, noffset, NULL));
-                       return ret;
-               }
-               verify_count++;
-       }
-
-       if (verify_count)
-               *no_sigsp = 0;
-
-       return 0;
-}
-
-/**
- * fit_config_check_sig() - Check the signature of a config
- *
- * @fit: FIT to check
- * @noffset: Offset of configuration node (e.g. /configurations/conf-1)
- * @required_keynode:  Offset in the control FDT of the required key node,
- *                     if any. If this is given, then the configuration wil not
- *                     pass verification unless that key is used. If this is
- *                     -1 then any signature will do.
- * @conf_noffset: Offset of the configuration subnode being checked (e.g.
- *      /configurations/conf-1/kernel)
- * @err_msgp:          In the event of an error, this will be pointed to a
- *                     help error string to display to the user.
- * @return 0 if all verified ok, <0 on error
- */
-static int fit_config_check_sig(const void *fit, int noffset,
-                               int required_keynode, int conf_noffset,
-                               char **err_msgp)
-{
-       static char * const exc_prop[] = {
-               "data",
-               "data-size",
-               "data-position",
-               "data-offset"
-       };
-
-       const char *prop, *end, *name;
-       struct image_sign_info info;
-       const uint32_t *strings;
-       const char *config_name;
-       uint8_t *fit_value;
-       int fit_value_len;
-       bool found_config;
-       int max_regions;
-       int i, prop_len;
-       char path[200];
-       int count;
-
-       config_name = fit_get_name(fit, conf_noffset, NULL);
-       debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(),
-             fit_get_name(fit, noffset, NULL),
-             fit_get_name(gd_fdt_blob(), required_keynode, NULL));
-       *err_msgp = NULL;
-       if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
-                                  err_msgp))
-               return -1;
-
-       if (fit_image_hash_get_value(fit, noffset, &fit_value,
-                                    &fit_value_len)) {
-               *err_msgp = "Can't get hash value property";
-               return -1;
-       }
-
-       /* Count the number of strings in the property */
-       prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len);
-       end = prop ? prop + prop_len : prop;
-       for (name = prop, count = 0; name < end; name++)
-               if (!*name)
-                       count++;
-       if (!count) {
-               *err_msgp = "Can't get hashed-nodes property";
-               return -1;
-       }
-
-       if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') {
-               *err_msgp = "hashed-nodes property must be null-terminated";
-               return -1;
-       }
-
-       /* Add a sanity check here since we are using the stack */
-       if (count > IMAGE_MAX_HASHED_NODES) {
-               *err_msgp = "Number of hashed nodes exceeds maximum";
-               return -1;
-       }
-
-       /* Create a list of node names from those strings */
-       char *node_inc[count];
-
-       debug("Hash nodes (%d):\n", count);
-       found_config = false;
-       for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
-               debug("   '%s'\n", name);
-               node_inc[i] = (char *)name;
-               if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) &&
-                   name[sizeof(FIT_CONFS_PATH) - 1] == '/' &&
-                   !strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) {
-                       debug("      (found config node %s)", config_name);
-                       found_config = true;
-               }
-       }
-       if (!found_config) {
-               *err_msgp = "Selected config not in hashed nodes";
-               return -1;
-       }
-
-       /*
-        * Each node can generate one region for each sub-node. Allow for
-        * 7 sub-nodes (hash-1, signature-1, etc.) and some extra.
-        */
-       max_regions = 20 + count * 7;
-       struct fdt_region fdt_regions[max_regions];
-
-       /* Get a list of regions to hash */
-       count = fdt_find_regions(fit, node_inc, count,
-                                exc_prop, ARRAY_SIZE(exc_prop),
-                                fdt_regions, max_regions - 1,
-                                path, sizeof(path), 0);
-       if (count < 0) {
-               *err_msgp = "Failed to hash configuration";
-               return -1;
-       }
-       if (count == 0) {
-               *err_msgp = "No data to hash";
-               return -1;
-       }
-       if (count >= max_regions - 1) {
-               *err_msgp = "Too many hash regions";
-               return -1;
-       }
-
-       /* Add the strings */
-       strings = fdt_getprop(fit, noffset, "hashed-strings", NULL);
-       if (strings) {
-               /*
-                * The strings region offset must be a static 0x0.
-                * This is set in tool/image-host.c
-                */
-               fdt_regions[count].offset = fdt_off_dt_strings(fit);
-               fdt_regions[count].size = fdt32_to_cpu(strings[1]);
-               count++;
-       }
-
-       /* Allocate the region list on the stack */
-       struct image_region region[count];
-
-       fit_region_make_list(fit, fdt_regions, count, region);
-       if (info.crypto->verify(&info, region, count, fit_value,
-                               fit_value_len)) {
-               *err_msgp = "Verification failed";
-               return -1;
-       }
-
-       return 0;
-}
-
-static int fit_config_verify_sig(const void *fit, int conf_noffset,
-                                const void *sig_blob, int sig_offset)
-{
-       int noffset;
-       char *err_msg = "No 'signature' subnode found";
-       int verified = 0;
-       int ret;
-
-       /* Process all hash subnodes of the component conf node */
-       fdt_for_each_subnode(noffset, fit, conf_noffset) {
-               const char *name = fit_get_name(fit, noffset, NULL);
-
-               if (!strncmp(name, FIT_SIG_NODENAME,
-                            strlen(FIT_SIG_NODENAME))) {
-                       ret = fit_config_check_sig(fit, noffset, sig_offset,
-                                                  conf_noffset, &err_msg);
-                       if (ret) {
-                               puts("- ");
-                       } else {
-                               puts("+ ");
-                               verified = 1;
-                               break;
-                       }
-               }
-       }
-
-       if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
-               err_msg = "Corrupted or truncated tree";
-               goto error;
-       }
-
-       if (verified)
-               return 0;
-
-error:
-       printf(" error!\n%s for '%s' hash node in '%s' config node\n",
-              err_msg, fit_get_name(fit, noffset, NULL),
-              fit_get_name(fit, conf_noffset, NULL));
-       return -EPERM;
-}
-
-static int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
-                                          const void *sig_blob)
-{
-       const char *name = fit_get_name(fit, conf_noffset, NULL);
-       int noffset;
-       int sig_node;
-       int verified = 0;
-       int reqd_sigs = 0;
-       bool reqd_policy_all = true;
-       const char *reqd_mode;
-
-       /*
-        * We don't support this since libfdt considers names with the
-        * name root but different @ suffix to be equal
-        */
-       if (strchr(name, '@')) {
-               printf("Configuration node '%s' contains '@'\n", name);
-               return -EPERM;
-       }
-
-       /* Work out what we need to verify */
-       sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
-       if (sig_node < 0) {
-               debug("%s: No signature node found: %s\n", __func__,
-                     fdt_strerror(sig_node));
-               return 0;
-       }
-
-       /* Get required-mode policy property from DTB */
-       reqd_mode = fdt_getprop(sig_blob, sig_node, "required-mode", NULL);
-       if (reqd_mode && !strcmp(reqd_mode, "any"))
-               reqd_policy_all = false;
-
-       debug("%s: required-mode policy set to '%s'\n", __func__,
-             reqd_policy_all ? "all" : "any");
-
-       fdt_for_each_subnode(noffset, sig_blob, sig_node) {
-               const char *required;
-               int ret;
-
-               required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
-                                      NULL);
-               if (!required || strcmp(required, "conf"))
-                       continue;
-
-               reqd_sigs++;
-
-               ret = fit_config_verify_sig(fit, conf_noffset, sig_blob,
-                                           noffset);
-               if (ret) {
-                       if (reqd_policy_all) {
-                               printf("Failed to verify required signature '%s'\n",
-                                      fit_get_name(sig_blob, noffset, NULL));
-                               return ret;
-                       }
-               } else {
-                       verified++;
-                       if (!reqd_policy_all)
-                               break;
-               }
-       }
-
-       if (reqd_sigs && !verified) {
-               printf("Failed to verify 'any' of the required signature(s)\n");
-               return -EPERM;
-       }
-
-       return 0;
-}
-
-int fit_config_verify(const void *fit, int conf_noffset)
-{
-       return fit_config_verify_required_sigs(fit, conf_noffset,
-                                              gd_fdt_blob());
-}
diff --git a/common/image-fit.c b/common/image-fit.c
deleted file mode 100644 (file)
index 33b4a46..0000000
+++ /dev/null
@@ -1,2448 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2013, Google Inc.
- *
- * (C) Copyright 2008 Semihalf
- *
- * (C) Copyright 2000-2006
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#define LOG_CATEGORY LOGC_BOOT
-
-#ifdef USE_HOSTCC
-#include "mkimage.h"
-#include <time.h>
-#include <linux/libfdt.h>
-#include <u-boot/crc.h>
-#else
-#include <linux/compiler.h>
-#include <linux/sizes.h>
-#include <common.h>
-#include <errno.h>
-#include <log.h>
-#include <mapmem.h>
-#include <asm/io.h>
-#include <malloc.h>
-#include <asm/global_data.h>
-#ifdef CONFIG_DM_HASH
-#include <dm.h>
-#include <u-boot/hash.h>
-#endif
-DECLARE_GLOBAL_DATA_PTR;
-#endif /* !USE_HOSTCC*/
-
-#include <bootm.h>
-#include <image.h>
-#include <bootstage.h>
-#include <linux/kconfig.h>
-#include <u-boot/crc.h>
-#include <u-boot/md5.h>
-#include <u-boot/sha1.h>
-#include <u-boot/sha256.h>
-#include <u-boot/sha512.h>
-
-/*****************************************************************************/
-/* New uImage format routines */
-/*****************************************************************************/
-#ifndef USE_HOSTCC
-static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
-               ulong *addr, const char **name)
-{
-       const char *sep;
-
-       *addr = addr_curr;
-       *name = NULL;
-
-       sep = strchr(spec, sepc);
-       if (sep) {
-               if (sep - spec > 0)
-                       *addr = hextoul(spec, NULL);
-
-               *name = sep + 1;
-               return 1;
-       }
-
-       return 0;
-}
-
-/**
- * fit_parse_conf - parse FIT configuration spec
- * @spec: input string, containing configuration spec
- * @add_curr: current image address (to be used as a possible default)
- * @addr: pointer to a ulong variable, will hold FIT image address of a given
- * configuration
- * @conf_name double pointer to a char, will hold pointer to a configuration
- * unit name
- *
- * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
- * where <addr> is a FIT image address that contains configuration
- * with a <conf> unit name.
- *
- * Address part is optional, and if omitted default add_curr will
- * be used instead.
- *
- * returns:
- *     1 if spec is a valid configuration string,
- *     addr and conf_name are set accordingly
- *     0 otherwise
- */
-int fit_parse_conf(const char *spec, ulong addr_curr,
-               ulong *addr, const char **conf_name)
-{
-       return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
-}
-
-/**
- * fit_parse_subimage - parse FIT subimage spec
- * @spec: input string, containing subimage spec
- * @add_curr: current image address (to be used as a possible default)
- * @addr: pointer to a ulong variable, will hold FIT image address of a given
- * subimage
- * @image_name: double pointer to a char, will hold pointer to a subimage name
- *
- * fit_parse_subimage() expects subimage spec in the form of
- * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
- * subimage with a <subimg> unit name.
- *
- * Address part is optional, and if omitted default add_curr will
- * be used instead.
- *
- * returns:
- *     1 if spec is a valid subimage string,
- *     addr and image_name are set accordingly
- *     0 otherwise
- */
-int fit_parse_subimage(const char *spec, ulong addr_curr,
-               ulong *addr, const char **image_name)
-{
-       return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
-}
-#endif /* !USE_HOSTCC */
-
-#ifdef USE_HOSTCC
-/* Host tools use these implementations for Cipher and Signature support */
-static void *host_blob;
-
-void image_set_host_blob(void *blob)
-{
-       host_blob = blob;
-}
-
-void *image_get_host_blob(void)
-{
-       return host_blob;
-}
-#endif /* USE_HOSTCC */
-
-static void fit_get_debug(const void *fit, int noffset,
-               char *prop_name, int err)
-{
-       debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
-             prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
-             fdt_strerror(err));
-}
-
-/**
- * fit_get_subimage_count - get component (sub-image) count
- * @fit: pointer to the FIT format image header
- * @images_noffset: offset of images node
- *
- * returns:
- *     number of image components
- */
-int fit_get_subimage_count(const void *fit, int images_noffset)
-{
-       int noffset;
-       int ndepth;
-       int count = 0;
-
-       /* Process its subnodes, print out component images details */
-       for (ndepth = 0, count = 0,
-               noffset = fdt_next_node(fit, images_noffset, &ndepth);
-            (noffset >= 0) && (ndepth > 0);
-            noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               if (ndepth == 1) {
-                       count++;
-               }
-       }
-
-       return count;
-}
-
-/**
- * fit_image_print_data() - prints out the hash node details
- * @fit: pointer to the FIT format image header
- * @noffset: offset of the hash node
- * @p: pointer to prefix string
- * @type: Type of information to print ("hash" or "sign")
- *
- * fit_image_print_data() lists properties for the processed hash node
- *
- * This function avoid using puts() since it prints a newline on the host
- * but does not in U-Boot.
- *
- * returns:
- *     no returned results
- */
-static void fit_image_print_data(const void *fit, int noffset, const char *p,
-                                const char *type)
-{
-       const char *keyname;
-       uint8_t *value;
-       int value_len;
-       char *algo;
-       const char *padding;
-       bool required;
-       int ret, i;
-
-       debug("%s  %s node:    '%s'\n", p, type,
-             fit_get_name(fit, noffset, NULL));
-       printf("%s  %s algo:    ", p, type);
-       if (fit_image_hash_get_algo(fit, noffset, &algo)) {
-               printf("invalid/unsupported\n");
-               return;
-       }
-       printf("%s", algo);
-       keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
-       required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL;
-       if (keyname)
-               printf(":%s", keyname);
-       if (required)
-               printf(" (required)");
-       printf("\n");
-
-       padding = fdt_getprop(fit, noffset, "padding", NULL);
-       if (padding)
-               printf("%s  %s padding: %s\n", p, type, padding);
-
-       ret = fit_image_hash_get_value(fit, noffset, &value,
-                                      &value_len);
-       printf("%s  %s value:   ", p, type);
-       if (ret) {
-               printf("unavailable\n");
-       } else {
-               for (i = 0; i < value_len; i++)
-                       printf("%02x", value[i]);
-               printf("\n");
-       }
-
-       debug("%s  %s len:     %d\n", p, type, value_len);
-
-       /* Signatures have a time stamp */
-       if (IMAGE_ENABLE_TIMESTAMP && keyname) {
-               time_t timestamp;
-
-               printf("%s  Timestamp:    ", p);
-               if (fit_get_timestamp(fit, noffset, &timestamp))
-                       printf("unavailable\n");
-               else
-                       genimg_print_time(timestamp);
-       }
-}
-
-/**
- * fit_image_print_verification_data() - prints out the hash/signature details
- * @fit: pointer to the FIT format image header
- * @noffset: offset of the hash or signature node
- * @p: pointer to prefix string
- *
- * This lists properties for the processed hash node
- *
- * returns:
- *     no returned results
- */
-static void fit_image_print_verification_data(const void *fit, int noffset,
-                                             const char *p)
-{
-       const char *name;
-
-       /*
-        * Check subnode name, must be equal to "hash" or "signature".
-        * Multiple hash/signature nodes require unique unit node
-        * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
-        */
-       name = fit_get_name(fit, noffset, NULL);
-       if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
-               fit_image_print_data(fit, noffset, p, "Hash");
-       } else if (!strncmp(name, FIT_SIG_NODENAME,
-                               strlen(FIT_SIG_NODENAME))) {
-               fit_image_print_data(fit, noffset, p, "Sign");
-       }
-}
-
-/**
- * fit_conf_print - prints out the FIT configuration details
- * @fit: pointer to the FIT format image header
- * @noffset: offset of the configuration node
- * @p: pointer to prefix string
- *
- * fit_conf_print() lists all mandatory properties for the processed
- * configuration node.
- *
- * returns:
- *     no returned results
- */
-static void fit_conf_print(const void *fit, int noffset, const char *p)
-{
-       char *desc;
-       const char *uname;
-       int ret;
-       int fdt_index, loadables_index;
-       int ndepth;
-
-       /* Mandatory properties */
-       ret = fit_get_desc(fit, noffset, &desc);
-       printf("%s  Description:  ", p);
-       if (ret)
-               printf("unavailable\n");
-       else
-               printf("%s\n", desc);
-
-       uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
-       printf("%s  Kernel:       ", p);
-       if (!uname)
-               printf("unavailable\n");
-       else
-               printf("%s\n", uname);
-
-       /* Optional properties */
-       uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
-       if (uname)
-               printf("%s  Init Ramdisk: %s\n", p, uname);
-
-       uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL);
-       if (uname)
-               printf("%s  Firmware:     %s\n", p, uname);
-
-       for (fdt_index = 0;
-            uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
-                                       fdt_index, NULL), uname;
-            fdt_index++) {
-               if (fdt_index == 0)
-                       printf("%s  FDT:          ", p);
-               else
-                       printf("%s                ", p);
-               printf("%s\n", uname);
-       }
-
-       uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
-       if (uname)
-               printf("%s  FPGA:         %s\n", p, uname);
-
-       /* Print out all of the specified loadables */
-       for (loadables_index = 0;
-            uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
-                                       loadables_index, NULL), uname;
-            loadables_index++) {
-               if (loadables_index == 0) {
-                       printf("%s  Loadables:    ", p);
-               } else {
-                       printf("%s                ", p);
-               }
-               printf("%s\n", uname);
-       }
-
-       /* Process all hash subnodes of the component configuration node */
-       for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth);
-            (noffset >= 0) && (ndepth > 0);
-            noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               if (ndepth == 1) {
-                       /* Direct child node of the component configuration node */
-                       fit_image_print_verification_data(fit, noffset, p);
-               }
-       }
-}
-
-/**
- * fit_print_contents - prints out the contents of the FIT format image
- * @fit: pointer to the FIT format image header
- * @p: pointer to prefix string
- *
- * fit_print_contents() formats a multi line FIT image contents description.
- * The routine prints out FIT image properties (root node level) followed by
- * the details of each component image.
- *
- * returns:
- *     no returned results
- */
-void fit_print_contents(const void *fit)
-{
-       char *desc;
-       char *uname;
-       int images_noffset;
-       int confs_noffset;
-       int noffset;
-       int ndepth;
-       int count = 0;
-       int ret;
-       const char *p;
-       time_t timestamp;
-
-       if (!CONFIG_IS_ENABLED(FIT_PRINT))
-               return;
-
-       /* Indent string is defined in header image.h */
-       p = IMAGE_INDENT_STRING;
-
-       /* Root node properties */
-       ret = fit_get_desc(fit, 0, &desc);
-       printf("%sFIT description: ", p);
-       if (ret)
-               printf("unavailable\n");
-       else
-               printf("%s\n", desc);
-
-       if (IMAGE_ENABLE_TIMESTAMP) {
-               ret = fit_get_timestamp(fit, 0, &timestamp);
-               printf("%sCreated:         ", p);
-               if (ret)
-                       printf("unavailable\n");
-               else
-                       genimg_print_time(timestamp);
-       }
-
-       /* Find images parent node offset */
-       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
-       if (images_noffset < 0) {
-               printf("Can't find images parent node '%s' (%s)\n",
-                      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
-               return;
-       }
-
-       /* Process its subnodes, print out component images details */
-       for (ndepth = 0, count = 0,
-               noffset = fdt_next_node(fit, images_noffset, &ndepth);
-            (noffset >= 0) && (ndepth > 0);
-            noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               if (ndepth == 1) {
-                       /*
-                        * Direct child node of the images parent node,
-                        * i.e. component image node.
-                        */
-                       printf("%s Image %u (%s)\n", p, count++,
-                              fit_get_name(fit, noffset, NULL));
-
-                       fit_image_print(fit, noffset, p);
-               }
-       }
-
-       /* Find configurations parent node offset */
-       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
-       if (confs_noffset < 0) {
-               debug("Can't get configurations parent node '%s' (%s)\n",
-                     FIT_CONFS_PATH, fdt_strerror(confs_noffset));
-               return;
-       }
-
-       /* get default configuration unit name from default property */
-       uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
-       if (uname)
-               printf("%s Default Configuration: '%s'\n", p, uname);
-
-       /* Process its subnodes, print out configurations details */
-       for (ndepth = 0, count = 0,
-               noffset = fdt_next_node(fit, confs_noffset, &ndepth);
-            (noffset >= 0) && (ndepth > 0);
-            noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               if (ndepth == 1) {
-                       /*
-                        * Direct child node of the configurations parent node,
-                        * i.e. configuration node.
-                        */
-                       printf("%s Configuration %u (%s)\n", p, count++,
-                              fit_get_name(fit, noffset, NULL));
-
-                       fit_conf_print(fit, noffset, p);
-               }
-       }
-}
-
-/**
- * fit_image_print - prints out the FIT component image details
- * @fit: pointer to the FIT format image header
- * @image_noffset: offset of the component image node
- * @p: pointer to prefix string
- *
- * fit_image_print() lists all mandatory properties for the processed component
- * image. If present, hash nodes are printed out as well. Load
- * address for images of type firmware is also printed out. Since the load
- * address is not mandatory for firmware images, it will be output as
- * "unavailable" when not present.
- *
- * returns:
- *     no returned results
- */
-void fit_image_print(const void *fit, int image_noffset, const char *p)
-{
-       char *desc;
-       uint8_t type, arch, os, comp;
-       size_t size;
-       ulong load, entry;
-       const void *data;
-       int noffset;
-       int ndepth;
-       int ret;
-
-       if (!CONFIG_IS_ENABLED(FIT_PRINT))
-               return;
-
-       /* Mandatory properties */
-       ret = fit_get_desc(fit, image_noffset, &desc);
-       printf("%s  Description:  ", p);
-       if (ret)
-               printf("unavailable\n");
-       else
-               printf("%s\n", desc);
-
-       if (IMAGE_ENABLE_TIMESTAMP) {
-               time_t timestamp;
-
-               ret = fit_get_timestamp(fit, 0, &timestamp);
-               printf("%s  Created:      ", p);
-               if (ret)
-                       printf("unavailable\n");
-               else
-                       genimg_print_time(timestamp);
-       }
-
-       fit_image_get_type(fit, image_noffset, &type);
-       printf("%s  Type:         %s\n", p, genimg_get_type_name(type));
-
-       fit_image_get_comp(fit, image_noffset, &comp);
-       printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp));
-
-       ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
-
-       if (!tools_build()) {
-               printf("%s  Data Start:   ", p);
-               if (ret) {
-                       printf("unavailable\n");
-               } else {
-                       void *vdata = (void *)data;
-
-                       printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
-               }
-       }
-
-       printf("%s  Data Size:    ", p);
-       if (ret)
-               printf("unavailable\n");
-       else
-               genimg_print_size(size);
-
-       /* Remaining, type dependent properties */
-       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
-           (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
-           (type == IH_TYPE_FLATDT)) {
-               fit_image_get_arch(fit, image_noffset, &arch);
-               printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch));
-       }
-
-       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK) ||
-           (type == IH_TYPE_FIRMWARE)) {
-               fit_image_get_os(fit, image_noffset, &os);
-               printf("%s  OS:           %s\n", p, genimg_get_os_name(os));
-       }
-
-       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
-           (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
-           (type == IH_TYPE_FPGA)) {
-               ret = fit_image_get_load(fit, image_noffset, &load);
-               printf("%s  Load Address: ", p);
-               if (ret)
-                       printf("unavailable\n");
-               else
-                       printf("0x%08lx\n", load);
-       }
-
-       /* optional load address for FDT */
-       if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
-               printf("%s  Load Address: 0x%08lx\n", p, load);
-
-       if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
-           (type == IH_TYPE_RAMDISK)) {
-               ret = fit_image_get_entry(fit, image_noffset, &entry);
-               printf("%s  Entry Point:  ", p);
-               if (ret)
-                       printf("unavailable\n");
-               else
-                       printf("0x%08lx\n", entry);
-       }
-
-       /* Process all hash subnodes of the component image node */
-       for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
-            (noffset >= 0) && (ndepth > 0);
-            noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               if (ndepth == 1) {
-                       /* Direct child node of the component image node */
-                       fit_image_print_verification_data(fit, noffset, p);
-               }
-       }
-}
-
-/**
- * fit_get_desc - get node description property
- * @fit: pointer to the FIT format image header
- * @noffset: node offset
- * @desc: double pointer to the char, will hold pointer to the description
- *
- * fit_get_desc() reads description property from a given node, if
- * description is found pointer to it is returned in third call argument.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_get_desc(const void *fit, int noffset, char **desc)
-{
-       int len;
-
-       *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
-       if (*desc == NULL) {
-               fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
-               return -1;
-       }
-
-       return 0;
-}
-
-/**
- * fit_get_timestamp - get node timestamp property
- * @fit: pointer to the FIT format image header
- * @noffset: node offset
- * @timestamp: pointer to the time_t, will hold read timestamp
- *
- * fit_get_timestamp() reads timestamp property from given node, if timestamp
- * is found and has a correct size its value is returned in third call
- * argument.
- *
- * returns:
- *     0, on success
- *     -1, on property read failure
- *     -2, on wrong timestamp size
- */
-int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
-{
-       int len;
-       const void *data;
-
-       data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
-       if (data == NULL) {
-               fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
-               return -1;
-       }
-       if (len != sizeof(uint32_t)) {
-               debug("FIT timestamp with incorrect size of (%u)\n", len);
-               return -2;
-       }
-
-       *timestamp = uimage_to_cpu(*((uint32_t *)data));
-       return 0;
-}
-
-/**
- * fit_image_get_node - get node offset for component image of a given unit name
- * @fit: pointer to the FIT format image header
- * @image_uname: component image node unit name
- *
- * fit_image_get_node() finds a component image (within the '/images'
- * node) of a provided unit name. If image is found its node offset is
- * returned to the caller.
- *
- * returns:
- *     image node offset when found (>=0)
- *     negative number on failure (FDT_ERR_* code)
- */
-int fit_image_get_node(const void *fit, const char *image_uname)
-{
-       int noffset, images_noffset;
-
-       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
-       if (images_noffset < 0) {
-               debug("Can't find images parent node '%s' (%s)\n",
-                     FIT_IMAGES_PATH, fdt_strerror(images_noffset));
-               return images_noffset;
-       }
-
-       noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
-       if (noffset < 0) {
-               debug("Can't get node offset for image unit name: '%s' (%s)\n",
-                     image_uname, fdt_strerror(noffset));
-       }
-
-       return noffset;
-}
-
-/**
- * fit_image_get_os - get os id for a given component image node
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @os: pointer to the uint8_t, will hold os numeric id
- *
- * fit_image_get_os() finds os property in a given component image node.
- * If the property is found, its (string) value is translated to the numeric
- * id which is returned to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
-{
-       int len;
-       const void *data;
-
-       /* Get OS name from property data */
-       data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
-       if (data == NULL) {
-               fit_get_debug(fit, noffset, FIT_OS_PROP, len);
-               *os = -1;
-               return -1;
-       }
-
-       /* Translate OS name to id */
-       *os = genimg_get_os_id(data);
-       return 0;
-}
-
-/**
- * fit_image_get_arch - get arch id for a given component image node
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @arch: pointer to the uint8_t, will hold arch numeric id
- *
- * fit_image_get_arch() finds arch property in a given component image node.
- * If the property is found, its (string) value is translated to the numeric
- * id which is returned to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
-{
-       int len;
-       const void *data;
-
-       /* Get architecture name from property data */
-       data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
-       if (data == NULL) {
-               fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
-               *arch = -1;
-               return -1;
-       }
-
-       /* Translate architecture name to id */
-       *arch = genimg_get_arch_id(data);
-       return 0;
-}
-
-/**
- * fit_image_get_type - get type id for a given component image node
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @type: pointer to the uint8_t, will hold type numeric id
- *
- * fit_image_get_type() finds type property in a given component image node.
- * If the property is found, its (string) value is translated to the numeric
- * id which is returned to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
-{
-       int len;
-       const void *data;
-
-       /* Get image type name from property data */
-       data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
-       if (data == NULL) {
-               fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
-               *type = -1;
-               return -1;
-       }
-
-       /* Translate image type name to id */
-       *type = genimg_get_type_id(data);
-       return 0;
-}
-
-/**
- * fit_image_get_comp - get comp id for a given component image node
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @comp: pointer to the uint8_t, will hold comp numeric id
- *
- * fit_image_get_comp() finds comp property in a given component image node.
- * If the property is found, its (string) value is translated to the numeric
- * id which is returned to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
-{
-       int len;
-       const void *data;
-
-       /* Get compression name from property data */
-       data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
-       if (data == NULL) {
-               fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
-               *comp = -1;
-               return -1;
-       }
-
-       /* Translate compression name to id */
-       *comp = genimg_get_comp_id(data);
-       return 0;
-}
-
-static int fit_image_get_address(const void *fit, int noffset, char *name,
-                         ulong *load)
-{
-       int len, cell_len;
-       const fdt32_t *cell;
-       uint64_t load64 = 0;
-
-       cell = fdt_getprop(fit, noffset, name, &len);
-       if (cell == NULL) {
-               fit_get_debug(fit, noffset, name, len);
-               return -1;
-       }
-
-       cell_len = len >> 2;
-       /* Use load64 to avoid compiling warning for 32-bit target */
-       while (cell_len--) {
-               load64 = (load64 << 32) | uimage_to_cpu(*cell);
-               cell++;
-       }
-
-       if (len > sizeof(ulong) && (uint32_t)(load64 >> 32)) {
-               printf("Unsupported %s address size\n", name);
-               return -1;
-       }
-
-       *load = (ulong)load64;
-
-       return 0;
-}
-/**
- * fit_image_get_load() - get load addr property for given component image node
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @load: pointer to the uint32_t, will hold load address
- *
- * fit_image_get_load() finds load address property in a given component
- * image node. If the property is found, its value is returned to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_get_load(const void *fit, int noffset, ulong *load)
-{
-       return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load);
-}
-
-/**
- * fit_image_get_entry() - get entry point address property
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @entry: pointer to the uint32_t, will hold entry point address
- *
- * This gets the entry point address property for a given component image
- * node.
- *
- * fit_image_get_entry() finds entry point address property in a given
- * component image node.  If the property is found, its value is returned
- * to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
-{
-       return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
-}
-
-/**
- * fit_image_get_data - get data property and its size for a given component image node
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @data: double pointer to void, will hold data property's data address
- * @size: pointer to size_t, will hold data property's data size
- *
- * fit_image_get_data() finds data property in a given component image node.
- * If the property is found its data start address and size are returned to
- * the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_get_data(const void *fit, int noffset,
-               const void **data, size_t *size)
-{
-       int len;
-
-       *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
-       if (*data == NULL) {
-               fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
-               *size = 0;
-               return -1;
-       }
-
-       *size = len;
-       return 0;
-}
-
-/**
- * Get 'data-offset' property from a given image node.
- *
- * @fit: pointer to the FIT image header
- * @noffset: component image node offset
- * @data_offset: holds the data-offset property
- *
- * returns:
- *     0, on success
- *     -ENOENT if the property could not be found
- */
-int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
-{
-       const fdt32_t *val;
-
-       val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL);
-       if (!val)
-               return -ENOENT;
-
-       *data_offset = fdt32_to_cpu(*val);
-
-       return 0;
-}
-
-/**
- * Get 'data-position' property from a given image node.
- *
- * @fit: pointer to the FIT image header
- * @noffset: component image node offset
- * @data_position: holds the data-position property
- *
- * returns:
- *     0, on success
- *     -ENOENT if the property could not be found
- */
-int fit_image_get_data_position(const void *fit, int noffset,
-                               int *data_position)
-{
-       const fdt32_t *val;
-
-       val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL);
-       if (!val)
-               return -ENOENT;
-
-       *data_position = fdt32_to_cpu(*val);
-
-       return 0;
-}
-
-/**
- * Get 'data-size' property from a given image node.
- *
- * @fit: pointer to the FIT image header
- * @noffset: component image node offset
- * @data_size: holds the data-size property
- *
- * returns:
- *     0, on success
- *     -ENOENT if the property could not be found
- */
-int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
-{
-       const fdt32_t *val;
-
-       val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL);
-       if (!val)
-               return -ENOENT;
-
-       *data_size = fdt32_to_cpu(*val);
-
-       return 0;
-}
-
-/**
- * Get 'data-size-unciphered' property from a given image node.
- *
- * @fit: pointer to the FIT image header
- * @noffset: component image node offset
- * @data_size: holds the data-size property
- *
- * returns:
- *     0, on success
- *     -ENOENT if the property could not be found
- */
-int fit_image_get_data_size_unciphered(const void *fit, int noffset,
-                                      size_t *data_size)
-{
-       const fdt32_t *val;
-
-       val = fdt_getprop(fit, noffset, "data-size-unciphered", NULL);
-       if (!val)
-               return -ENOENT;
-
-       *data_size = (size_t)fdt32_to_cpu(*val);
-
-       return 0;
-}
-
-/**
- * fit_image_get_data_and_size - get data and its size including
- *                              both embedded and external data
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @data: double pointer to void, will hold data property's data address
- * @size: pointer to size_t, will hold data property's data size
- *
- * fit_image_get_data_and_size() finds data and its size including
- * both embedded and external data. If the property is found
- * its data start address and size are returned to the caller.
- *
- * returns:
- *     0, on success
- *     otherwise, on failure
- */
-int fit_image_get_data_and_size(const void *fit, int noffset,
-                               const void **data, size_t *size)
-{
-       bool external_data = false;
-       int offset;
-       int len;
-       int ret;
-
-       if (!fit_image_get_data_position(fit, noffset, &offset)) {
-               external_data = true;
-       } else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
-               external_data = true;
-               /*
-                * For FIT with external data, figure out where
-                * the external images start. This is the base
-                * for the data-offset properties in each image.
-                */
-               offset += ((fdt_totalsize(fit) + 3) & ~3);
-       }
-
-       if (external_data) {
-               debug("External Data\n");
-               ret = fit_image_get_data_size(fit, noffset, &len);
-               if (!ret) {
-                       *data = fit + offset;
-                       *size = len;
-               }
-       } else {
-               ret = fit_image_get_data(fit, noffset, data, size);
-       }
-
-       return ret;
-}
-
-/**
- * fit_image_hash_get_algo - get hash algorithm name
- * @fit: pointer to the FIT format image header
- * @noffset: hash node offset
- * @algo: double pointer to char, will hold pointer to the algorithm name
- *
- * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
- * If the property is found its data start address is returned to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
-{
-       int len;
-
-       *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
-       if (*algo == NULL) {
-               fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
-               return -1;
-       }
-
-       return 0;
-}
-
-/**
- * fit_image_hash_get_value - get hash value and length
- * @fit: pointer to the FIT format image header
- * @noffset: hash node offset
- * @value: double pointer to uint8_t, will hold address of a hash value data
- * @value_len: pointer to an int, will hold hash data length
- *
- * fit_image_hash_get_value() finds hash value property in a given hash node.
- * If the property is found its data start address and size are returned to
- * the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
-                               int *value_len)
-{
-       int len;
-
-       *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
-       if (*value == NULL) {
-               fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
-               *value_len = 0;
-               return -1;
-       }
-
-       *value_len = len;
-       return 0;
-}
-
-/**
- * fit_image_hash_get_ignore - get hash ignore flag
- * @fit: pointer to the FIT format image header
- * @noffset: hash node offset
- * @ignore: pointer to an int, will hold hash ignore flag
- *
- * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
- * If the property is found and non-zero, the hash algorithm is not verified by
- * u-boot automatically.
- *
- * returns:
- *     0, on ignore not found
- *     value, on ignore found
- */
-static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
-{
-       int len;
-       int *value;
-
-       value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
-       if (value == NULL || len != sizeof(int))
-               *ignore = 0;
-       else
-               *ignore = *value;
-
-       return 0;
-}
-
-/**
- * fit_image_cipher_get_algo - get cipher algorithm name
- * @fit: pointer to the FIT format image header
- * @noffset: cipher node offset
- * @algo: double pointer to char, will hold pointer to the algorithm name
- *
- * fit_image_cipher_get_algo() finds cipher algorithm property in a given
- * cipher node. If the property is found its data start address is returned
- * to the caller.
- *
- * returns:
- *     0, on success
- *     -1, on failure
- */
-int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo)
-{
-       int len;
-
-       *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
-       if (!*algo) {
-               fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
-               return -1;
-       }
-
-       return 0;
-}
-
-ulong fit_get_end(const void *fit)
-{
-       return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
-}
-
-/**
- * fit_set_timestamp - set node timestamp property
- * @fit: pointer to the FIT format image header
- * @noffset: node offset
- * @timestamp: timestamp value to be set
- *
- * fit_set_timestamp() attempts to set timestamp property in the requested
- * node and returns operation status to the caller.
- *
- * returns:
- *     0, on success
- *     -ENOSPC if no space in device tree, -1 for other error
- */
-int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
-{
-       uint32_t t;
-       int ret;
-
-       t = cpu_to_uimage(timestamp);
-       ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
-                               sizeof(uint32_t));
-       if (ret) {
-               debug("Can't set '%s' property for '%s' node (%s)\n",
-                     FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
-                     fdt_strerror(ret));
-               return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
-       }
-
-       return 0;
-}
-
-/**
- * calculate_hash - calculate and return hash for provided input data
- * @data: pointer to the input data
- * @data_len: data length
- * @algo: requested hash algorithm
- * @value: pointer to the char, will hold hash value data (caller must
- * allocate enough free space)
- * value_len: length of the calculated hash
- *
- * calculate_hash() computes input data hash according to the requested
- * algorithm.
- * Resulting hash value is placed in caller provided 'value' buffer, length
- * of the calculated hash is returned via value_len pointer argument.
- *
- * returns:
- *     0, on success
- *    -1, when algo is unsupported
- */
-int calculate_hash(const void *data, int data_len, const char *name,
-                       uint8_t *value, int *value_len)
-{
-#if !defined(USE_HOSTCC) && defined(CONFIG_DM_HASH)
-       int rc;
-       enum HASH_ALGO hash_algo;
-       struct udevice *dev;
-
-       rc = uclass_get_device(UCLASS_HASH, 0, &dev);
-       if (rc) {
-               debug("failed to get hash device, rc=%d\n", rc);
-               return -1;
-       }
-
-       hash_algo = hash_algo_lookup_by_name(algo);
-       if (hash_algo == HASH_ALGO_INVALID) {
-               debug("Unsupported hash algorithm\n");
-               return -1;
-       };
-
-       rc = hash_digest_wd(dev, hash_algo, data, data_len, value, CHUNKSZ);
-       if (rc) {
-               debug("failed to get hash value, rc=%d\n", rc);
-               return -1;
-       }
-
-       *value_len = hash_algo_digest_size(hash_algo);
-#else
-       struct hash_algo *algo;
-       int ret;
-
-       ret = hash_lookup_algo(name, &algo);
-       if (ret < 0) {
-               debug("Unsupported hash alogrithm\n");
-               return -1;
-       }
-
-       algo->hash_func_ws(data, data_len, value, algo->chunk_size);
-       *value_len = algo->digest_size;
-#endif
-
-       return 0;
-}
-
-static int fit_image_check_hash(const void *fit, int noffset, const void *data,
-                               size_t size, char **err_msgp)
-{
-       uint8_t value[FIT_MAX_HASH_LEN];
-       int value_len;
-       char *algo;
-       uint8_t *fit_value;
-       int fit_value_len;
-       int ignore;
-
-       *err_msgp = NULL;
-
-       if (fit_image_hash_get_algo(fit, noffset, &algo)) {
-               *err_msgp = "Can't get hash algo property";
-               return -1;
-       }
-       printf("%s", algo);
-
-       if (!tools_build()) {
-               fit_image_hash_get_ignore(fit, noffset, &ignore);
-               if (ignore) {
-                       printf("-skipped ");
-                       return 0;
-               }
-       }
-
-       if (fit_image_hash_get_value(fit, noffset, &fit_value,
-                                    &fit_value_len)) {
-               *err_msgp = "Can't get hash value property";
-               return -1;
-       }
-
-       if (calculate_hash(data, size, algo, value, &value_len)) {
-               *err_msgp = "Unsupported hash algorithm";
-               return -1;
-       }
-
-       if (value_len != fit_value_len) {
-               *err_msgp = "Bad hash value len";
-               return -1;
-       } else if (memcmp(value, fit_value, value_len) != 0) {
-               *err_msgp = "Bad hash value";
-               return -1;
-       }
-
-       return 0;
-}
-
-int fit_image_verify_with_data(const void *fit, int image_noffset,
-                              const void *data, size_t size)
-{
-       int             noffset = 0;
-       char            *err_msg = "";
-       int verify_all = 1;
-       int ret;
-
-       /* Verify all required signatures */
-       if (FIT_IMAGE_ENABLE_VERIFY &&
-           fit_image_verify_required_sigs(fit, image_noffset, data, size,
-                                          gd_fdt_blob(), &verify_all)) {
-               err_msg = "Unable to verify required signature";
-               goto error;
-       }
-
-       /* Process all hash subnodes of the component image node */
-       fdt_for_each_subnode(noffset, fit, image_noffset) {
-               const char *name = fit_get_name(fit, noffset, NULL);
-
-               /*
-                * Check subnode name, must be equal to "hash".
-                * Multiple hash nodes require unique unit node
-                * names, e.g. hash-1, hash-2, etc.
-                */
-               if (!strncmp(name, FIT_HASH_NODENAME,
-                            strlen(FIT_HASH_NODENAME))) {
-                       if (fit_image_check_hash(fit, noffset, data, size,
-                                                &err_msg))
-                               goto error;
-                       puts("+ ");
-               } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
-                               !strncmp(name, FIT_SIG_NODENAME,
-                                       strlen(FIT_SIG_NODENAME))) {
-                       ret = fit_image_check_sig(fit, noffset, data,
-                                                       size, -1, &err_msg);
-
-                       /*
-                        * Show an indication on failure, but do not return
-                        * an error. Only keys marked 'required' can cause
-                        * an image validation failure. See the call to
-                        * fit_image_verify_required_sigs() above.
-                        */
-                       if (ret)
-                               puts("- ");
-                       else
-                               puts("+ ");
-               }
-       }
-
-       if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
-               err_msg = "Corrupted or truncated tree";
-               goto error;
-       }
-
-       return 1;
-
-error:
-       printf(" error!\n%s for '%s' hash node in '%s' image node\n",
-              err_msg, fit_get_name(fit, noffset, NULL),
-              fit_get_name(fit, image_noffset, NULL));
-       return 0;
-}
-
-/**
- * fit_image_verify - verify data integrity
- * @fit: pointer to the FIT format image header
- * @image_noffset: component image node offset
- *
- * fit_image_verify() goes over component image hash nodes,
- * re-calculates each data hash and compares with the value stored in hash
- * node.
- *
- * returns:
- *     1, if all hashes are valid
- *     0, otherwise (or on error)
- */
-int fit_image_verify(const void *fit, int image_noffset)
-{
-       const char *name = fit_get_name(fit, image_noffset, NULL);
-       const void      *data;
-       size_t          size;
-       char            *err_msg = "";
-
-       if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
-               /*
-                * We don't support this since libfdt considers names with the
-                * name root but different @ suffix to be equal
-                */
-               err_msg = "Node name contains @";
-               goto err;
-       }
-       /* Get image data and data length */
-       if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
-               err_msg = "Can't get image data/size";
-               goto err;
-       }
-
-       return fit_image_verify_with_data(fit, image_noffset, data, size);
-
-err:
-       printf("error!\n%s in '%s' image node\n", err_msg,
-              fit_get_name(fit, image_noffset, NULL));
-       return 0;
-}
-
-/**
- * fit_all_image_verify - verify data integrity for all images
- * @fit: pointer to the FIT format image header
- *
- * fit_all_image_verify() goes over all images in the FIT and
- * for every images checks if all it's hashes are valid.
- *
- * returns:
- *     1, if all hashes of all images are valid
- *     0, otherwise (or on error)
- */
-int fit_all_image_verify(const void *fit)
-{
-       int images_noffset;
-       int noffset;
-       int ndepth;
-       int count;
-
-       /* Find images parent node offset */
-       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
-       if (images_noffset < 0) {
-               printf("Can't find images parent node '%s' (%s)\n",
-                      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
-               return 0;
-       }
-
-       /* Process all image subnodes, check hashes for each */
-       printf("## Checking hash(es) for FIT Image at %08lx ...\n",
-              (ulong)fit);
-       for (ndepth = 0, count = 0,
-            noffset = fdt_next_node(fit, images_noffset, &ndepth);
-                       (noffset >= 0) && (ndepth > 0);
-                       noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               if (ndepth == 1) {
-                       /*
-                        * Direct child node of the images parent node,
-                        * i.e. component image node.
-                        */
-                       printf("   Hash(es) for Image %u (%s): ", count,
-                              fit_get_name(fit, noffset, NULL));
-                       count++;
-
-                       if (!fit_image_verify(fit, noffset))
-                               return 0;
-                       printf("\n");
-               }
-       }
-       return 1;
-}
-
-static int fit_image_uncipher(const void *fit, int image_noffset,
-                             void **data, size_t *size)
-{
-       int cipher_noffset, ret;
-       void *dst;
-       size_t size_dst;
-
-       cipher_noffset = fdt_subnode_offset(fit, image_noffset,
-                                           FIT_CIPHER_NODENAME);
-       if (cipher_noffset < 0)
-               return 0;
-
-       ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
-                                    *data, *size, &dst, &size_dst);
-       if (ret)
-               goto out;
-
-       *data = dst;
-       *size = size_dst;
-
- out:
-       return ret;
-}
-
-/**
- * fit_image_check_os - check whether image node is of a given os type
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @os: requested image os
- *
- * fit_image_check_os() reads image os property and compares its numeric
- * id with the requested os. Comparison result is returned to the caller.
- *
- * returns:
- *     1 if image is of given os type
- *     0 otherwise (or on error)
- */
-int fit_image_check_os(const void *fit, int noffset, uint8_t os)
-{
-       uint8_t image_os;
-
-       if (fit_image_get_os(fit, noffset, &image_os))
-               return 0;
-       return (os == image_os);
-}
-
-/**
- * fit_image_check_arch - check whether image node is of a given arch
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @arch: requested imagearch
- *
- * fit_image_check_arch() reads image arch property and compares its numeric
- * id with the requested arch. Comparison result is returned to the caller.
- *
- * returns:
- *     1 if image is of given arch
- *     0 otherwise (or on error)
- */
-int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
-{
-       uint8_t image_arch;
-       int aarch32_support = 0;
-
-       /* Let's assume that sandbox can load any architecture */
-       if (IS_ENABLED(CONFIG_SANDBOX))
-               return true;
-
-       if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
-               aarch32_support = 1;
-
-       if (fit_image_get_arch(fit, noffset, &image_arch))
-               return 0;
-       return (arch == image_arch) ||
-               (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
-               (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
-                aarch32_support);
-}
-
-/**
- * fit_image_check_type - check whether image node is of a given type
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @type: requested image type
- *
- * fit_image_check_type() reads image type property and compares its numeric
- * id with the requested type. Comparison result is returned to the caller.
- *
- * returns:
- *     1 if image is of given type
- *     0 otherwise (or on error)
- */
-int fit_image_check_type(const void *fit, int noffset, uint8_t type)
-{
-       uint8_t image_type;
-
-       if (fit_image_get_type(fit, noffset, &image_type))
-               return 0;
-       return (type == image_type);
-}
-
-/**
- * fit_image_check_comp - check whether image node uses given compression
- * @fit: pointer to the FIT format image header
- * @noffset: component image node offset
- * @comp: requested image compression type
- *
- * fit_image_check_comp() reads image compression property and compares its
- * numeric id with the requested compression type. Comparison result is
- * returned to the caller.
- *
- * returns:
- *     1 if image uses requested compression
- *     0 otherwise (or on error)
- */
-int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
-{
-       uint8_t image_comp;
-
-       if (fit_image_get_comp(fit, noffset, &image_comp))
-               return 0;
-       return (comp == image_comp);
-}
-
-/**
- * fdt_check_no_at() - Check for nodes whose names contain '@'
- *
- * This checks the parent node and all subnodes recursively
- *
- * @fit: FIT to check
- * @parent: Parent node to check
- * @return 0 if OK, -EADDRNOTAVAIL is a node has a name containing '@'
- */
-static int fdt_check_no_at(const void *fit, int parent)
-{
-       const char *name;
-       int node;
-       int ret;
-
-       name = fdt_get_name(fit, parent, NULL);
-       if (!name || strchr(name, '@'))
-               return -EADDRNOTAVAIL;
-
-       fdt_for_each_subnode(node, fit, parent) {
-               ret = fdt_check_no_at(fit, node);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-int fit_check_format(const void *fit, ulong size)
-{
-       int ret;
-
-       /* A FIT image must be a valid FDT */
-       ret = fdt_check_header(fit);
-       if (ret) {
-               log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
-                         ret);
-               return -ENOEXEC;
-       }
-
-       if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
-               /*
-                * If we are not given the size, make do wtih calculating it.
-                * This is not as secure, so we should consider a flag to
-                * control this.
-                */
-               if (size == IMAGE_SIZE_INVAL)
-                       size = fdt_totalsize(fit);
-               ret = fdt_check_full(fit, size);
-               if (ret)
-                       ret = -EINVAL;
-
-               /*
-                * U-Boot stopped using unit addressed in 2017. Since libfdt
-                * can match nodes ignoring any unit address, signature
-                * verification can see the wrong node if one is inserted with
-                * the same name as a valid node but with a unit address
-                * attached. Protect against this by disallowing unit addresses.
-                */
-               if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
-                       ret = fdt_check_no_at(fit, 0);
-
-                       if (ret) {
-                               log_debug("FIT check error %d\n", ret);
-                               return ret;
-                       }
-               }
-               if (ret) {
-                       log_debug("FIT check error %d\n", ret);
-                       return ret;
-               }
-       }
-
-       /* mandatory / node 'description' property */
-       if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
-               log_debug("Wrong FIT format: no description\n");
-               return -ENOMSG;
-       }
-
-       if (IMAGE_ENABLE_TIMESTAMP) {
-               /* mandatory / node 'timestamp' property */
-               if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
-                       log_debug("Wrong FIT format: no timestamp\n");
-                       return -EBADMSG;
-               }
-       }
-
-       /* mandatory subimages parent '/images' node */
-       if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
-               log_debug("Wrong FIT format: no images parent node\n");
-               return -ENOENT;
-       }
-
-       return 0;
-}
-
-/**
- * fit_conf_find_compat
- * @fit: pointer to the FIT format image header
- * @fdt: pointer to the device tree to compare against
- *
- * fit_conf_find_compat() attempts to find the configuration whose fdt is the
- * most compatible with the passed in device tree.
- *
- * Example:
- *
- * / o image-tree
- *   |-o images
- *   | |-o fdt-1
- *   | |-o fdt-2
- *   |
- *   |-o configurations
- *     |-o config-1
- *     | |-fdt = fdt-1
- *     |
- *     |-o config-2
- *       |-fdt = fdt-2
- *
- * / o U-Boot fdt
- *   |-compatible = "foo,bar", "bim,bam"
- *
- * / o kernel fdt1
- *   |-compatible = "foo,bar",
- *
- * / o kernel fdt2
- *   |-compatible = "bim,bam", "baz,biz"
- *
- * Configuration 1 would be picked because the first string in U-Boot's
- * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
- * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
- *
- * As an optimization, the compatible property from the FDT's root node can be
- * copied into the configuration node in the FIT image. This is required to
- * match configurations with compressed FDTs.
- *
- * returns:
- *     offset to the configuration to use if one was found
- *     -1 otherwise
- */
-int fit_conf_find_compat(const void *fit, const void *fdt)
-{
-       int ndepth = 0;
-       int noffset, confs_noffset, images_noffset;
-       const void *fdt_compat;
-       int fdt_compat_len;
-       int best_match_offset = 0;
-       int best_match_pos = 0;
-
-       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
-       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
-       if (confs_noffset < 0 || images_noffset < 0) {
-               debug("Can't find configurations or images nodes.\n");
-               return -1;
-       }
-
-       fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
-       if (!fdt_compat) {
-               debug("Fdt for comparison has no \"compatible\" property.\n");
-               return -1;
-       }
-
-       /*
-        * Loop over the configurations in the FIT image.
-        */
-       for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
-                       (noffset >= 0) && (ndepth > 0);
-                       noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               const void *fdt;
-               const char *kfdt_name;
-               int kfdt_noffset, compat_noffset;
-               const char *cur_fdt_compat;
-               int len;
-               size_t sz;
-               int i;
-
-               if (ndepth > 1)
-                       continue;
-
-               /* If there's a compat property in the config node, use that. */
-               if (fdt_getprop(fit, noffset, "compatible", NULL)) {
-                       fdt = fit;                /* search in FIT image */
-                       compat_noffset = noffset; /* search under config node */
-               } else {        /* Otherwise extract it from the kernel FDT. */
-                       kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
-                       if (!kfdt_name) {
-                               debug("No fdt property found.\n");
-                               continue;
-                       }
-                       kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
-                                                         kfdt_name);
-                       if (kfdt_noffset < 0) {
-                               debug("No image node named \"%s\" found.\n",
-                                     kfdt_name);
-                               continue;
-                       }
-
-                       if (!fit_image_check_comp(fit, kfdt_noffset,
-                                                 IH_COMP_NONE)) {
-                               debug("Can't extract compat from \"%s\" "
-                                     "(compressed)\n", kfdt_name);
-                               continue;
-                       }
-
-                       /* search in this config's kernel FDT */
-                       if (fit_image_get_data_and_size(fit, kfdt_noffset,
-                                                       &fdt, &sz)) {
-                               debug("Failed to get fdt \"%s\".\n", kfdt_name);
-                               continue;
-                       }
-
-                       compat_noffset = 0;  /* search kFDT under root node */
-               }
-
-               len = fdt_compat_len;
-               cur_fdt_compat = fdt_compat;
-               /*
-                * Look for a match for each U-Boot compatibility string in
-                * turn in the compat string property.
-                */
-               for (i = 0; len > 0 &&
-                    (!best_match_offset || best_match_pos > i); i++) {
-                       int cur_len = strlen(cur_fdt_compat) + 1;
-
-                       if (!fdt_node_check_compatible(fdt, compat_noffset,
-                                                      cur_fdt_compat)) {
-                               best_match_offset = noffset;
-                               best_match_pos = i;
-                               break;
-                       }
-                       len -= cur_len;
-                       cur_fdt_compat += cur_len;
-               }
-       }
-       if (!best_match_offset) {
-               debug("No match found.\n");
-               return -1;
-       }
-
-       return best_match_offset;
-}
-
-int fit_conf_get_node(const void *fit, const char *conf_uname)
-{
-       int noffset, confs_noffset;
-       int len;
-       const char *s;
-       char *conf_uname_copy = NULL;
-
-       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
-       if (confs_noffset < 0) {
-               debug("Can't find configurations parent node '%s' (%s)\n",
-                     FIT_CONFS_PATH, fdt_strerror(confs_noffset));
-               return confs_noffset;
-       }
-
-       if (conf_uname == NULL) {
-               /* get configuration unit name from the default property */
-               debug("No configuration specified, trying default...\n");
-               if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
-                       noffset = fit_find_config_node(fit);
-                       if (noffset < 0)
-                               return noffset;
-                       conf_uname = fdt_get_name(fit, noffset, NULL);
-               } else {
-                       conf_uname = (char *)fdt_getprop(fit, confs_noffset,
-                                                        FIT_DEFAULT_PROP, &len);
-                       if (conf_uname == NULL) {
-                               fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
-                                             len);
-                               return len;
-                       }
-               }
-               debug("Found default configuration: '%s'\n", conf_uname);
-       }
-
-       s = strchr(conf_uname, '#');
-       if (s) {
-               len = s - conf_uname;
-               conf_uname_copy = malloc(len + 1);
-               if (!conf_uname_copy) {
-                       debug("Can't allocate uname copy: '%s'\n",
-                                       conf_uname);
-                       return -ENOMEM;
-               }
-               memcpy(conf_uname_copy, conf_uname, len);
-               conf_uname_copy[len] = '\0';
-               conf_uname = conf_uname_copy;
-       }
-
-       noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
-       if (noffset < 0) {
-               debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
-                     conf_uname, fdt_strerror(noffset));
-       }
-
-       if (conf_uname_copy)
-               free(conf_uname_copy);
-
-       return noffset;
-}
-
-int fit_conf_get_prop_node_count(const void *fit, int noffset,
-               const char *prop_name)
-{
-       return fdt_stringlist_count(fit, noffset, prop_name);
-}
-
-int fit_conf_get_prop_node_index(const void *fit, int noffset,
-               const char *prop_name, int index)
-{
-       const char *uname;
-       int len;
-
-       /* get kernel image unit name from configuration kernel property */
-       uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
-       if (uname == NULL)
-               return len;
-
-       return fit_image_get_node(fit, uname);
-}
-
-int fit_conf_get_prop_node(const void *fit, int noffset,
-               const char *prop_name)
-{
-       return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
-}
-
-static int fit_image_select(const void *fit, int rd_noffset, int verify)
-{
-       fit_image_print(fit, rd_noffset, "   ");
-
-       if (verify) {
-               puts("   Verifying Hash Integrity ... ");
-               if (!fit_image_verify(fit, rd_noffset)) {
-                       puts("Bad Data Hash\n");
-                       return -EACCES;
-               }
-               puts("OK\n");
-       }
-
-       return 0;
-}
-
-int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
-                       ulong addr)
-{
-       int cfg_noffset;
-       void *fit_hdr;
-       int noffset;
-
-       debug("*  %s: using config '%s' from image at 0x%08lx\n",
-             prop_name, images->fit_uname_cfg, addr);
-
-       /* Check whether configuration has this property defined */
-       fit_hdr = map_sysmem(addr, 0);
-       cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
-       if (cfg_noffset < 0) {
-               debug("*  %s: no such config\n", prop_name);
-               return -EINVAL;
-       }
-
-       noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
-       if (noffset < 0) {
-               debug("*  %s: no '%s' in config\n", prop_name, prop_name);
-               return -ENOENT;
-       }
-
-       return noffset;
-}
-
-/**
- * fit_get_image_type_property() - get property name for IH_TYPE_...
- *
- * @return the properly name where we expect to find the image in the
- * config node
- */
-static const char *fit_get_image_type_property(int type)
-{
-       /*
-        * This is sort-of available in the uimage_type[] table in image.c
-        * but we don't have access to the short name, and "fdt" is different
-        * anyway. So let's just keep it here.
-        */
-       switch (type) {
-       case IH_TYPE_FLATDT:
-               return FIT_FDT_PROP;
-       case IH_TYPE_KERNEL:
-               return FIT_KERNEL_PROP;
-       case IH_TYPE_FIRMWARE:
-               return FIT_FIRMWARE_PROP;
-       case IH_TYPE_RAMDISK:
-               return FIT_RAMDISK_PROP;
-       case IH_TYPE_X86_SETUP:
-               return FIT_SETUP_PROP;
-       case IH_TYPE_LOADABLE:
-               return FIT_LOADABLE_PROP;
-       case IH_TYPE_FPGA:
-               return FIT_FPGA_PROP;
-       case IH_TYPE_STANDALONE:
-               return FIT_STANDALONE_PROP;
-       }
-
-       return "unknown";
-}
-
-int fit_image_load(bootm_headers_t *images, ulong addr,
-                  const char **fit_unamep, const char **fit_uname_configp,
-                  int arch, int image_type, int bootstage_id,
-                  enum fit_load_op load_op, ulong *datap, ulong *lenp)
-{
-       int cfg_noffset, noffset;
-       const char *fit_uname;
-       const char *fit_uname_config;
-       const char *fit_base_uname_config;
-       const void *fit;
-       void *buf;
-       void *loadbuf;
-       size_t size;
-       int type_ok, os_ok;
-       ulong load, load_end, data, len;
-       uint8_t os, comp;
-       const char *prop_name;
-       int ret;
-
-       fit = map_sysmem(addr, 0);
-       fit_uname = fit_unamep ? *fit_unamep : NULL;
-       fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
-       fit_base_uname_config = NULL;
-       prop_name = fit_get_image_type_property(image_type);
-       printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
-
-       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
-       ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
-       if (ret) {
-               printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
-               if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
-                       printf("Signature checking prevents use of unit addresses (@) in nodes\n");
-               bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
-               return ret;
-       }
-       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
-       if (fit_uname) {
-               /* get FIT component image node offset */
-               bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
-               noffset = fit_image_get_node(fit, fit_uname);
-       } else {
-               /*
-                * no image node unit name, try to get config
-                * node first. If config unit node name is NULL
-                * fit_conf_get_node() will try to find default config node
-                */
-               bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
-               if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
-                       cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
-               } else {
-                       cfg_noffset = fit_conf_get_node(fit,
-                                                       fit_uname_config);
-               }
-               if (cfg_noffset < 0) {
-                       puts("Could not find configuration node\n");
-                       bootstage_error(bootstage_id +
-                                       BOOTSTAGE_SUB_NO_UNIT_NAME);
-                       return -ENOENT;
-               }
-
-               fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
-               printf("   Using '%s' configuration\n", fit_base_uname_config);
-               /* Remember this config */
-               if (image_type == IH_TYPE_KERNEL)
-                       images->fit_uname_cfg = fit_base_uname_config;
-
-               if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
-                       puts("   Verifying Hash Integrity ... ");
-                       if (fit_config_verify(fit, cfg_noffset)) {
-                               puts("Bad Data Hash\n");
-                               bootstage_error(bootstage_id +
-                                       BOOTSTAGE_SUB_HASH);
-                               return -EACCES;
-                       }
-                       puts("OK\n");
-               }
-
-               bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
-
-               noffset = fit_conf_get_prop_node(fit, cfg_noffset,
-                                                prop_name);
-               fit_uname = fit_get_name(fit, noffset, NULL);
-       }
-       if (noffset < 0) {
-               printf("Could not find subimage node type '%s'\n", prop_name);
-               bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
-               return -ENOENT;
-       }
-
-       printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);
-
-       ret = fit_image_select(fit, noffset, images->verify);
-       if (ret) {
-               bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
-               return ret;
-       }
-
-       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
-       if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
-               if (!fit_image_check_target_arch(fit, noffset)) {
-                       puts("Unsupported Architecture\n");
-                       bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
-                       return -ENOEXEC;
-               }
-       }
-
-#ifndef USE_HOSTCC
-       {
-       uint8_t os_arch;
-
-       fit_image_get_arch(fit, noffset, &os_arch);
-       images->os.arch = os_arch;
-       }
-#endif
-
-       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
-       type_ok = fit_image_check_type(fit, noffset, image_type) ||
-                 fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
-                 fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
-                 (image_type == IH_TYPE_KERNEL &&
-                  fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
-
-       os_ok = image_type == IH_TYPE_FLATDT ||
-               image_type == IH_TYPE_FPGA ||
-               fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
-               fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
-               fit_image_check_os(fit, noffset, IH_OS_TEE) ||
-               fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
-               fit_image_check_os(fit, noffset, IH_OS_EFI) ||
-               fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
-
-       /*
-        * If either of the checks fail, we should report an error, but
-        * if the image type is coming from the "loadables" field, we
-        * don't care what it is
-        */
-       if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
-               fit_image_get_os(fit, noffset, &os);
-               printf("No %s %s %s Image\n",
-                      genimg_get_os_name(os),
-                      genimg_get_arch_name(arch),
-                      genimg_get_type_name(image_type));
-               bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
-               return -EIO;
-       }
-
-       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
-
-       /* get image data address and length */
-       if (fit_image_get_data_and_size(fit, noffset,
-                                       (const void **)&buf, &size)) {
-               printf("Could not find %s subimage data!\n", prop_name);
-               bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
-               return -ENOENT;
-       }
-
-       /* Decrypt data before uncompress/move */
-       if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
-               puts("   Decrypting Data ... ");
-               if (fit_image_uncipher(fit, noffset, &buf, &size)) {
-                       puts("Error\n");
-                       return -EACCES;
-               }
-               puts("OK\n");
-       }
-
-       /* perform any post-processing on the image data */
-       if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
-               board_fit_image_post_process(fit, noffset, &buf, &size);
-
-       len = (ulong)size;
-
-       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
-
-       data = map_to_sysmem(buf);
-       load = data;
-       if (load_op == FIT_LOAD_IGNORED) {
-               /* Don't load */
-       } else if (fit_image_get_load(fit, noffset, &load)) {
-               if (load_op == FIT_LOAD_REQUIRED) {
-                       printf("Can't get %s subimage load address!\n",
-                              prop_name);
-                       bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
-                       return -EBADF;
-               }
-       } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
-               ulong image_start, image_end;
-
-               /*
-                * move image data to the load address,
-                * make sure we don't overwrite initial image
-                */
-               image_start = addr;
-               image_end = addr + fit_get_size(fit);
-
-               load_end = load + len;
-               if (image_type != IH_TYPE_KERNEL &&
-                   load < image_end && load_end > image_start) {
-                       printf("Error: %s overwritten\n", prop_name);
-                       return -EXDEV;
-               }
-
-               printf("   Loading %s from 0x%08lx to 0x%08lx\n",
-                      prop_name, data, load);
-       } else {
-               load = data;    /* No load address specified */
-       }
-
-       comp = IH_COMP_NONE;
-       loadbuf = buf;
-       /* Kernel images get decompressed later in bootm_load_os(). */
-       if (!fit_image_get_comp(fit, noffset, &comp) &&
-           comp != IH_COMP_NONE &&
-           !(image_type == IH_TYPE_KERNEL ||
-             image_type == IH_TYPE_KERNEL_NOLOAD ||
-             image_type == IH_TYPE_RAMDISK)) {
-               ulong max_decomp_len = len * 20;
-               if (load == data) {
-                       loadbuf = malloc(max_decomp_len);
-                       load = map_to_sysmem(loadbuf);
-               } else {
-                       loadbuf = map_sysmem(load, max_decomp_len);
-               }
-               if (image_decomp(comp, load, data, image_type,
-                               loadbuf, buf, len, max_decomp_len, &load_end)) {
-                       printf("Error decompressing %s\n", prop_name);
-
-                       return -ENOEXEC;
-               }
-               len = load_end - load;
-       } else if (load != data) {
-               loadbuf = map_sysmem(load, len);
-               memcpy(loadbuf, buf, len);
-       }
-
-       if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
-               puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
-                    " please fix your .its file!\n");
-
-       /* verify that image data is a proper FDT blob */
-       if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
-               puts("Subimage data is not a FDT");
-               return -ENOEXEC;
-       }
-
-       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
-
-       *datap = load;
-       *lenp = len;
-       if (fit_unamep)
-               *fit_unamep = (char *)fit_uname;
-       if (fit_uname_configp)
-               *fit_uname_configp = (char *)(fit_uname_config ? :
-                                             fit_base_uname_config);
-
-       return noffset;
-}
-
-int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
-                       ulong *setup_start, ulong *setup_len)
-{
-       int noffset;
-       ulong addr;
-       ulong len;
-       int ret;
-
-       addr = map_to_sysmem(images->fit_hdr_os);
-       noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
-       if (noffset < 0)
-               return noffset;
-
-       ret = fit_image_load(images, addr, NULL, NULL, arch,
-                            IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
-                            FIT_LOAD_REQUIRED, setup_start, &len);
-
-       return ret;
-}
-
-#ifndef USE_HOSTCC
-int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
-                  const char **fit_unamep, const char **fit_uname_configp,
-                  int arch, ulong *datap, ulong *lenp)
-{
-       int fdt_noffset, cfg_noffset, count;
-       const void *fit;
-       const char *fit_uname = NULL;
-       const char *fit_uname_config = NULL;
-       char *fit_uname_config_copy = NULL;
-       char *next_config = NULL;
-       ulong load, len;
-#ifdef CONFIG_OF_LIBFDT_OVERLAY
-       ulong image_start, image_end;
-       ulong ovload, ovlen, ovcopylen;
-       const char *uconfig;
-       const char *uname;
-       void *base, *ov, *ovcopy = NULL;
-       int i, err, noffset, ov_noffset;
-#endif
-
-       fit_uname = fit_unamep ? *fit_unamep : NULL;
-
-       if (fit_uname_configp && *fit_uname_configp) {
-               fit_uname_config_copy = strdup(*fit_uname_configp);
-               if (!fit_uname_config_copy)
-                       return -ENOMEM;
-
-               next_config = strchr(fit_uname_config_copy, '#');
-               if (next_config)
-                       *next_config++ = '\0';
-               if (next_config - 1 > fit_uname_config_copy)
-                       fit_uname_config = fit_uname_config_copy;
-       }
-
-       fdt_noffset = fit_image_load(images,
-               addr, &fit_uname, &fit_uname_config,
-               arch, IH_TYPE_FLATDT,
-               BOOTSTAGE_ID_FIT_FDT_START,
-               FIT_LOAD_OPTIONAL, &load, &len);
-
-       if (fdt_noffset < 0)
-               goto out;
-
-       debug("fit_uname=%s, fit_uname_config=%s\n",
-                       fit_uname ? fit_uname : "<NULL>",
-                       fit_uname_config ? fit_uname_config : "<NULL>");
-
-       fit = map_sysmem(addr, 0);
-
-       cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
-
-       /* single blob, or error just return as well */
-       count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
-       if (count <= 1 && !next_config)
-               goto out;
-
-       /* we need to apply overlays */
-
-#ifdef CONFIG_OF_LIBFDT_OVERLAY
-       image_start = addr;
-       image_end = addr + fit_get_size(fit);
-       /* verify that relocation took place by load address not being in fit */
-       if (load >= image_start && load < image_end) {
-               /* check is simplified; fit load checks for overlaps */
-               printf("Overlayed FDT requires relocation\n");
-               fdt_noffset = -EBADF;
-               goto out;
-       }
-
-       base = map_sysmem(load, len);
-
-       /* apply extra configs in FIT first, followed by args */
-       for (i = 1; ; i++) {
-               if (i < count) {
-                       noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
-                                                              FIT_FDT_PROP, i);
-                       uname = fit_get_name(fit, noffset, NULL);
-                       uconfig = NULL;
-               } else {
-                       if (!next_config)
-                               break;
-                       uconfig = next_config;
-                       next_config = strchr(next_config, '#');
-                       if (next_config)
-                               *next_config++ = '\0';
-                       uname = NULL;
-
-                       /*
-                        * fit_image_load() would load the first FDT from the
-                        * extra config only when uconfig is specified.
-                        * Check if the extra config contains multiple FDTs and
-                        * if so, load them.
-                        */
-                       cfg_noffset = fit_conf_get_node(fit, uconfig);
-
-                       i = 0;
-                       count = fit_conf_get_prop_node_count(fit, cfg_noffset,
-                                                            FIT_FDT_PROP);
-               }
-
-               debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
-
-               ov_noffset = fit_image_load(images,
-                       addr, &uname, &uconfig,
-                       arch, IH_TYPE_FLATDT,
-                       BOOTSTAGE_ID_FIT_FDT_START,
-                       FIT_LOAD_IGNORED, &ovload, &ovlen);
-               if (ov_noffset < 0) {
-                       printf("load of %s failed\n", uname);
-                       continue;
-               }
-               debug("%s loaded at 0x%08lx len=0x%08lx\n",
-                               uname, ovload, ovlen);
-               ov = map_sysmem(ovload, ovlen);
-
-               ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
-               ovcopy = malloc(ovcopylen);
-               if (!ovcopy) {
-                       printf("failed to duplicate DTO before application\n");
-                       fdt_noffset = -ENOMEM;
-                       goto out;
-               }
-
-               err = fdt_open_into(ov, ovcopy, ovcopylen);
-               if (err < 0) {
-                       printf("failed on fdt_open_into for DTO\n");
-                       fdt_noffset = err;
-                       goto out;
-               }
-
-               base = map_sysmem(load, len + ovlen);
-               err = fdt_open_into(base, base, len + ovlen);
-               if (err < 0) {
-                       printf("failed on fdt_open_into\n");
-                       fdt_noffset = err;
-                       goto out;
-               }
-
-               /* the verbose method prints out messages on error */
-               err = fdt_overlay_apply_verbose(base, ovcopy);
-               if (err < 0) {
-                       fdt_noffset = err;
-                       goto out;
-               }
-               fdt_pack(base);
-               len = fdt_totalsize(base);
-
-               free(ovcopy);
-               ovcopy = NULL;
-       }
-#else
-       printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
-       fdt_noffset = -EBADF;
-#endif
-
-out:
-       if (datap)
-               *datap = load;
-       if (lenp)
-               *lenp = len;
-       if (fit_unamep)
-               *fit_unamep = fit_uname;
-       if (fit_uname_configp)
-               *fit_uname_configp = fit_uname_config;
-
-#ifdef CONFIG_OF_LIBFDT_OVERLAY
-       if (ovcopy)
-               free(ovcopy);
-#endif
-       if (fit_uname_config_copy)
-               free(fit_uname_config_copy);
-       return fdt_noffset;
-}
-#endif
diff --git a/common/image-host.c b/common/image-host.c
deleted file mode 100644 (file)
index 20a9521..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Image code used by host tools (and not boards)
- *
- * (C) Copyright 2008 Semihalf
- *
- * (C) Copyright 2000-2006
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#include <time.h>
-
-void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
-{
-       memmove(to, from, len);
-}
-
-void genimg_print_size(uint32_t size)
-{
-       printf("%d Bytes = %.2f KiB = %.2f MiB\n", size, (double)size / 1.024e3,
-              (double)size / 1.048576e6);
-}
-
-void genimg_print_time(time_t timestamp)
-{
-       printf("%s", ctime(&timestamp));
-}
diff --git a/common/image-sig.c b/common/image-sig.c
deleted file mode 100644 (file)
index 1aa0b58..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2013, Google Inc.
- */
-
-#include <common.h>
-#include <log.h>
-#include <malloc.h>
-#include <asm/global_data.h>
-DECLARE_GLOBAL_DATA_PTR;
-#include <image.h>
-#include <relocate.h>
-#include <u-boot/ecdsa.h>
-#include <u-boot/rsa.h>
-#include <u-boot/hash-checksum.h>
-
-#define IMAGE_MAX_HASHED_NODES         100
-
-struct checksum_algo checksum_algos[] = {
-       {
-               .name = "sha1",
-               .checksum_len = SHA1_SUM_LEN,
-               .der_len = SHA1_DER_LEN,
-               .der_prefix = sha1_der_prefix,
-               .calculate = hash_calculate,
-       },
-       {
-               .name = "sha256",
-               .checksum_len = SHA256_SUM_LEN,
-               .der_len = SHA256_DER_LEN,
-               .der_prefix = sha256_der_prefix,
-               .calculate = hash_calculate,
-       },
-#ifdef CONFIG_SHA384
-       {
-               .name = "sha384",
-               .checksum_len = SHA384_SUM_LEN,
-               .der_len = SHA384_DER_LEN,
-               .der_prefix = sha384_der_prefix,
-               .calculate = hash_calculate,
-       },
-#endif
-#ifdef CONFIG_SHA512
-       {
-               .name = "sha512",
-               .checksum_len = SHA512_SUM_LEN,
-               .der_len = SHA512_DER_LEN,
-               .der_prefix = sha512_der_prefix,
-               .calculate = hash_calculate,
-       },
-#endif
-
-};
-
-struct checksum_algo *image_get_checksum_algo(const char *full_name)
-{
-       int i;
-       const char *name;
-
-       if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
-               static bool done;
-
-               if (!done) {
-                       done = true;
-                       for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
-                               struct checksum_algo *algo = &checksum_algos[i];
-
-                               MANUAL_RELOC(algo->name);
-                               MANUAL_RELOC(algo->calculate);
-                       }
-               }
-       }
-
-       for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
-               name = checksum_algos[i].name;
-               /* Make sure names match and next char is a comma */
-               if (!strncmp(name, full_name, strlen(name)) &&
-                   full_name[strlen(name)] == ',')
-                       return &checksum_algos[i];
-       }
-
-       return NULL;
-}
-
-struct crypto_algo *image_get_crypto_algo(const char *full_name)
-{
-       struct crypto_algo *crypto, *end;
-       const char *name;
-
-       if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
-               static bool done;
-
-               if (!done) {
-                       done = true;
-                       crypto = ll_entry_start(struct crypto_algo, cryptos);
-                       end = ll_entry_end(struct crypto_algo, cryptos);
-                       for (; crypto < end; crypto++) {
-                               MANUAL_RELOC(crypto->name);
-                               MANUAL_RELOC(crypto->verify);
-                       }
-               }
-       }
-
-       /* Move name to after the comma */
-       name = strchr(full_name, ',');
-       if (!name)
-               return NULL;
-       name += 1;
-
-       crypto = ll_entry_start(struct crypto_algo, cryptos);
-       end = ll_entry_end(struct crypto_algo, cryptos);
-       for (; crypto < end; crypto++) {
-               if (!strcmp(crypto->name, name))
-                       return crypto;
-       }
-
-       /* Not found */
-       return NULL;
-}
-
-struct padding_algo *image_get_padding_algo(const char *name)
-{
-       struct padding_algo *padding, *end;
-
-       if (!name)
-               return NULL;
-
-       padding = ll_entry_start(struct padding_algo, paddings);
-       end = ll_entry_end(struct padding_algo, paddings);
-       for (; padding < end; padding++) {
-               if (!strcmp(padding->name, name))
-                       return padding;
-       }
-
-       return NULL;
-}
diff --git a/common/image.c b/common/image.c
deleted file mode 100644 (file)
index 3fa60b5..0000000
+++ /dev/null
@@ -1,738 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2008 Semihalf
- *
- * (C) Copyright 2000-2006
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- */
-
-#ifndef USE_HOSTCC
-#include <common.h>
-#include <env.h>
-#include <lmb.h>
-#include <log.h>
-#include <malloc.h>
-#include <u-boot/crc.h>
-
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
-#include <status_led.h>
-#endif
-
-#if CONFIG_IS_ENABLED(FIT) || CONFIG_IS_ENABLED(OF_LIBFDT)
-#include <linux/libfdt.h>
-#include <fdt_support.h>
-#endif
-
-#include <asm/global_data.h>
-#include <u-boot/md5.h>
-#include <u-boot/sha1.h>
-#include <linux/errno.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_CMD_BDI
-extern int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc,
-                    char *const argv[]);
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/* Set this if we have less than 4 MB of malloc() space */
-#if CONFIG_SYS_MALLOC_LEN < (4096 * 1024)
-#define CONSERVE_MEMORY                true
-#else
-#define CONSERVE_MEMORY                false
-#endif
-
-#else /* USE_HOSTCC */
-#include "mkimage.h"
-#include <u-boot/md5.h>
-#include <time.h>
-
-#ifndef __maybe_unused
-# define __maybe_unused                /* unimplemented */
-#endif
-
-#define CONSERVE_MEMORY                false
-
-#endif /* !USE_HOSTCC*/
-
-#include <abuf.h>
-#include <bzlib.h>
-#include <display_options.h>
-#include <gzip.h>
-#include <image.h>
-#include <imximage.h>
-#include <relocate.h>
-#include <linux/lzo.h>
-#include <linux/zstd.h>
-#include <linux/kconfig.h>
-#include <lzma/LzmaTypes.h>
-#include <lzma/LzmaDec.h>
-#include <lzma/LzmaTools.h>
-#include <u-boot/crc.h>
-#include <u-boot/lz4.h>
-
-static const table_entry_t uimage_arch[] = {
-       {       IH_ARCH_INVALID,        "invalid",      "Invalid ARCH", },
-       {       IH_ARCH_ALPHA,          "alpha",        "Alpha",        },
-       {       IH_ARCH_ARM,            "arm",          "ARM",          },
-       {       IH_ARCH_I386,           "x86",          "Intel x86",    },
-       {       IH_ARCH_IA64,           "ia64",         "IA64",         },
-       {       IH_ARCH_M68K,           "m68k",         "M68K",         },
-       {       IH_ARCH_MICROBLAZE,     "microblaze",   "MicroBlaze",   },
-       {       IH_ARCH_MIPS,           "mips",         "MIPS",         },
-       {       IH_ARCH_MIPS64,         "mips64",       "MIPS 64 Bit",  },
-       {       IH_ARCH_NIOS2,          "nios2",        "NIOS II",      },
-       {       IH_ARCH_PPC,            "powerpc",      "PowerPC",      },
-       {       IH_ARCH_PPC,            "ppc",          "PowerPC",      },
-       {       IH_ARCH_S390,           "s390",         "IBM S390",     },
-       {       IH_ARCH_SH,             "sh",           "SuperH",       },
-       {       IH_ARCH_SPARC,          "sparc",        "SPARC",        },
-       {       IH_ARCH_SPARC64,        "sparc64",      "SPARC 64 Bit", },
-       {       IH_ARCH_BLACKFIN,       "blackfin",     "Blackfin",     },
-       {       IH_ARCH_AVR32,          "avr32",        "AVR32",        },
-       {       IH_ARCH_NDS32,          "nds32",        "NDS32",        },
-       {       IH_ARCH_OPENRISC,       "or1k",         "OpenRISC 1000",},
-       {       IH_ARCH_SANDBOX,        "sandbox",      "Sandbox",      },
-       {       IH_ARCH_ARM64,          "arm64",        "AArch64",      },
-       {       IH_ARCH_ARC,            "arc",          "ARC",          },
-       {       IH_ARCH_X86_64,         "x86_64",       "AMD x86_64",   },
-       {       IH_ARCH_XTENSA,         "xtensa",       "Xtensa",       },
-       {       IH_ARCH_RISCV,          "riscv",        "RISC-V",       },
-       {       -1,                     "",             "",             },
-};
-
-static const table_entry_t uimage_os[] = {
-       {       IH_OS_INVALID,  "invalid",      "Invalid OS",           },
-       {       IH_OS_ARM_TRUSTED_FIRMWARE, "arm-trusted-firmware", "ARM Trusted Firmware"  },
-       {       IH_OS_LINUX,    "linux",        "Linux",                },
-#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
-       {       IH_OS_LYNXOS,   "lynxos",       "LynxOS",               },
-#endif
-       {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
-       {       IH_OS_OSE,      "ose",          "Enea OSE",             },
-       {       IH_OS_PLAN9,    "plan9",        "Plan 9",               },
-       {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
-       {       IH_OS_TEE,      "tee",          "Trusted Execution Environment" },
-       {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
-       {       IH_OS_VXWORKS,  "vxworks",      "VxWorks",              },
-#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
-       {       IH_OS_QNX,      "qnx",          "QNX",                  },
-#endif
-#if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
-       {       IH_OS_INTEGRITY,"integrity",    "INTEGRITY",            },
-#endif
-#ifdef USE_HOSTCC
-       {       IH_OS_4_4BSD,   "4_4bsd",       "4_4BSD",               },
-       {       IH_OS_DELL,     "dell",         "Dell",                 },
-       {       IH_OS_ESIX,     "esix",         "Esix",                 },
-       {       IH_OS_FREEBSD,  "freebsd",      "FreeBSD",              },
-       {       IH_OS_IRIX,     "irix",         "Irix",                 },
-       {       IH_OS_NCR,      "ncr",          "NCR",                  },
-       {       IH_OS_OPENBSD,  "openbsd",      "OpenBSD",              },
-       {       IH_OS_PSOS,     "psos",         "pSOS",                 },
-       {       IH_OS_SCO,      "sco",          "SCO",                  },
-       {       IH_OS_SOLARIS,  "solaris",      "Solaris",              },
-       {       IH_OS_SVR4,     "svr4",         "SVR4",                 },
-#endif
-#if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC)
-       {       IH_OS_OPENRTOS, "openrtos",     "OpenRTOS",             },
-#endif
-       {       IH_OS_OPENSBI,  "opensbi",      "RISC-V OpenSBI",       },
-       {       IH_OS_EFI,      "efi",          "EFI Firmware" },
-
-       {       -1,             "",             "",                     },
-};
-
-static const table_entry_t uimage_type[] = {
-       {       IH_TYPE_AISIMAGE,   "aisimage",   "Davinci AIS image",},
-       {       IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",   },
-       {       IH_TYPE_FIRMWARE,   "firmware",   "Firmware",           },
-       {       IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",   },
-       {       IH_TYPE_GPIMAGE,    "gpimage",    "TI Keystone SPL Image",},
-       {       IH_TYPE_KERNEL,     "kernel",     "Kernel Image",       },
-       {       IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
-       {       IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
-       {       IH_TYPE_IMXIMAGE,   "imximage",   "Freescale i.MX Boot Image",},
-       {       IH_TYPE_IMX8IMAGE,  "imx8image",  "NXP i.MX8 Boot Image",},
-       {       IH_TYPE_IMX8MIMAGE, "imx8mimage", "NXP i.MX8M Boot Image",},
-       {       IH_TYPE_INVALID,    "invalid",    "Invalid Image",      },
-       {       IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
-       {       IH_TYPE_OMAPIMAGE,  "omapimage",  "TI OMAP SPL With GP CH",},
-       {       IH_TYPE_PBLIMAGE,   "pblimage",   "Freescale PBL Boot Image",},
-       {       IH_TYPE_RAMDISK,    "ramdisk",    "RAMDisk Image",      },
-       {       IH_TYPE_SCRIPT,     "script",     "Script",             },
-       {       IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SoCFPGA CV/AV preloader",},
-       {       IH_TYPE_SOCFPGAIMAGE_V1, "socfpgaimage_v1", "Altera SoCFPGA A10 preloader",},
-       {       IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
-       {       IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
-       {       IH_TYPE_MXSIMAGE,   "mxsimage",   "Freescale MXS Boot Image",},
-       {       IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",},
-       {       IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
-       {       IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
-       {       IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
-       {       IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
-       {       IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
-       {       IH_TYPE_VYBRIDIMAGE, "vybridimage",  "Vybrid Boot Image", },
-       {       IH_TYPE_ZYNQIMAGE,  "zynqimage",  "Xilinx Zynq Boot Image" },
-       {       IH_TYPE_ZYNQMPIMAGE, "zynqmpimage", "Xilinx ZynqMP Boot Image" },
-       {       IH_TYPE_ZYNQMPBIF,  "zynqmpbif",  "Xilinx ZynqMP Boot Image (bif)" },
-       {       IH_TYPE_FPGA,       "fpga",       "FPGA Image" },
-       {       IH_TYPE_TEE,        "tee",        "Trusted Execution Environment Image",},
-       {       IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },
-       {       IH_TYPE_PMMC,        "pmmc",        "TI Power Management Micro-Controller Firmware",},
-       {       IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" },
-       {       IH_TYPE_MTKIMAGE,   "mtk_image",   "MediaTek BootROM loadable Image" },
-       {       IH_TYPE_COPRO, "copro", "Coprocessor Image"},
-       {       IH_TYPE_SUNXI_EGON, "sunxi_egon",  "Allwinner eGON Boot Image" },
-       {       -1,                 "",           "",                   },
-};
-
-static const table_entry_t uimage_comp[] = {
-       {       IH_COMP_NONE,   "none",         "uncompressed",         },
-       {       IH_COMP_BZIP2,  "bzip2",        "bzip2 compressed",     },
-       {       IH_COMP_GZIP,   "gzip",         "gzip compressed",      },
-       {       IH_COMP_LZMA,   "lzma",         "lzma compressed",      },
-       {       IH_COMP_LZO,    "lzo",          "lzo compressed",       },
-       {       IH_COMP_LZ4,    "lz4",          "lz4 compressed",       },
-       {       IH_COMP_ZSTD,   "zstd",         "zstd compressed",      },
-       {       -1,             "",             "",                     },
-};
-
-struct table_info {
-       const char *desc;
-       int count;
-       const table_entry_t *table;
-};
-
-static const struct comp_magic_map image_comp[] = {
-       {       IH_COMP_BZIP2,  "bzip2",        {0x42, 0x5a},},
-       {       IH_COMP_GZIP,   "gzip",         {0x1f, 0x8b},},
-       {       IH_COMP_LZMA,   "lzma",         {0x5d, 0x00},},
-       {       IH_COMP_LZO,    "lzo",          {0x89, 0x4c},},
-       {       IH_COMP_LZ4,    "lz4",          {0x04, 0x22},},
-       {       IH_COMP_ZSTD,   "zstd",         {0x28, 0xb5},},
-       {       IH_COMP_NONE,   "none",         {},     },
-};
-
-static const struct table_info table_info[IH_COUNT] = {
-       { "architecture", IH_ARCH_COUNT, uimage_arch },
-       { "compression", IH_COMP_COUNT, uimage_comp },
-       { "operating system", IH_OS_COUNT, uimage_os },
-       { "image type", IH_TYPE_COUNT, uimage_type },
-};
-
-/*****************************************************************************/
-/* Legacy format routines */
-/*****************************************************************************/
-int image_check_hcrc(const image_header_t *hdr)
-{
-       ulong hcrc;
-       ulong len = image_get_header_size();
-       image_header_t header;
-
-       /* Copy header so we can blank CRC field for re-calculation */
-       memmove(&header, (char *)hdr, image_get_header_size());
-       image_set_hcrc(&header, 0);
-
-       hcrc = crc32(0, (unsigned char *)&header, len);
-
-       return (hcrc == image_get_hcrc(hdr));
-}
-
-int image_check_dcrc(const image_header_t *hdr)
-{
-       ulong data = image_get_data(hdr);
-       ulong len = image_get_data_size(hdr);
-       ulong dcrc = crc32_wd(0, (unsigned char *)data, len, CHUNKSZ_CRC32);
-
-       return (dcrc == image_get_dcrc(hdr));
-}
-
-/**
- * image_multi_count - get component (sub-image) count
- * @hdr: pointer to the header of the multi component image
- *
- * image_multi_count() returns number of components in a multi
- * component image.
- *
- * Note: no checking of the image type is done, caller must pass
- * a valid multi component image.
- *
- * returns:
- *     number of components
- */
-ulong image_multi_count(const image_header_t *hdr)
-{
-       ulong i, count = 0;
-       uint32_t *size;
-
-       /* get start of the image payload, which in case of multi
-        * component images that points to a table of component sizes */
-       size = (uint32_t *)image_get_data(hdr);
-
-       /* count non empty slots */
-       for (i = 0; size[i]; ++i)
-               count++;
-
-       return count;
-}
-
-/**
- * image_multi_getimg - get component data address and size
- * @hdr: pointer to the header of the multi component image
- * @idx: index of the requested component
- * @data: pointer to a ulong variable, will hold component data address
- * @len: pointer to a ulong variable, will hold component size
- *
- * image_multi_getimg() returns size and data address for the requested
- * component in a multi component image.
- *
- * Note: no checking of the image type is done, caller must pass
- * a valid multi component image.
- *
- * returns:
- *     data address and size of the component, if idx is valid
- *     0 in data and len, if idx is out of range
- */
-void image_multi_getimg(const image_header_t *hdr, ulong idx,
-                       ulong *data, ulong *len)
-{
-       int i;
-       uint32_t *size;
-       ulong offset, count, img_data;
-
-       /* get number of component */
-       count = image_multi_count(hdr);
-
-       /* get start of the image payload, which in case of multi
-        * component images that points to a table of component sizes */
-       size = (uint32_t *)image_get_data(hdr);
-
-       /* get address of the proper component data start, which means
-        * skipping sizes table (add 1 for last, null entry) */
-       img_data = image_get_data(hdr) + (count + 1) * sizeof(uint32_t);
-
-       if (idx < count) {
-               *len = uimage_to_cpu(size[idx]);
-               offset = 0;
-
-               /* go over all indices preceding requested component idx */
-               for (i = 0; i < idx; i++) {
-                       /* add up i-th component size, rounding up to 4 bytes */
-                       offset += (uimage_to_cpu(size[i]) + 3) & ~3 ;
-               }
-
-               /* calculate idx-th component data address */
-               *data = img_data + offset;
-       } else {
-               *len = 0;
-               *data = 0;
-       }
-}
-
-static void image_print_type(const image_header_t *hdr)
-{
-       const char __maybe_unused *os, *arch, *type, *comp;
-
-       os = genimg_get_os_name(image_get_os(hdr));
-       arch = genimg_get_arch_name(image_get_arch(hdr));
-       type = genimg_get_type_name(image_get_type(hdr));
-       comp = genimg_get_comp_name(image_get_comp(hdr));
-
-       printf("%s %s %s (%s)\n", arch, os, type, comp);
-}
-
-/**
- * image_print_contents - prints out the contents of the legacy format image
- * @ptr: pointer to the legacy format image header
- * @p: pointer to prefix string
- *
- * image_print_contents() formats a multi line legacy image contents description.
- * The routine prints out all header fields followed by the size/offset data
- * for MULTI/SCRIPT images.
- *
- * returns:
- *     no returned results
- */
-void image_print_contents(const void *ptr)
-{
-       const image_header_t *hdr = (const image_header_t *)ptr;
-       const char __maybe_unused *p;
-
-       p = IMAGE_INDENT_STRING;
-       printf("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name(hdr));
-       if (IMAGE_ENABLE_TIMESTAMP) {
-               printf("%sCreated:      ", p);
-               genimg_print_time((time_t)image_get_time(hdr));
-       }
-       printf("%sImage Type:   ", p);
-       image_print_type(hdr);
-       printf("%sData Size:    ", p);
-       genimg_print_size(image_get_data_size(hdr));
-       printf("%sLoad Address: %08x\n", p, image_get_load(hdr));
-       printf("%sEntry Point:  %08x\n", p, image_get_ep(hdr));
-
-       if (image_check_type(hdr, IH_TYPE_MULTI) ||
-                       image_check_type(hdr, IH_TYPE_SCRIPT)) {
-               int i;
-               ulong data, len;
-               ulong count = image_multi_count(hdr);
-
-               printf("%sContents:\n", p);
-               for (i = 0; i < count; i++) {
-                       image_multi_getimg(hdr, i, &data, &len);
-
-                       printf("%s   Image %d: ", p, i);
-                       genimg_print_size(len);
-
-                       if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) {
-                               /*
-                                * the user may need to know offsets
-                                * if planning to do something with
-                                * multiple files
-                                */
-                               printf("%s    Offset = 0x%08lx\n", p, data);
-                       }
-               }
-       } else if (image_check_type(hdr, IH_TYPE_FIRMWARE_IVT)) {
-               printf("HAB Blocks:   0x%08x   0x0000   0x%08x\n",
-                       image_get_load(hdr) - image_get_header_size(),
-                       (int)(image_get_size(hdr) + image_get_header_size()
-                       + sizeof(flash_header_v2_t) - 0x2060));
-       }
-}
-
-/**
- * print_decomp_msg() - Print a suitable decompression/loading message
- *
- * @type:      OS type (IH_OS_...)
- * @comp_type: Compression type being used (IH_COMP_...)
- * @is_xip:    true if the load address matches the image start
- */
-static void print_decomp_msg(int comp_type, int type, bool is_xip)
-{
-       const char *name = genimg_get_type_name(type);
-
-       if (comp_type == IH_COMP_NONE)
-               printf("   %s %s\n", is_xip ? "XIP" : "Loading", name);
-       else
-               printf("   Uncompressing %s\n", name);
-}
-
-int image_decomp_type(const unsigned char *buf, ulong len)
-{
-       const struct comp_magic_map *cmagic = image_comp;
-
-       if (len < 2)
-               return -EINVAL;
-
-       for (; cmagic->comp_id > 0; cmagic++) {
-               if (!memcmp(buf, cmagic->magic, 2))
-                       break;
-       }
-
-       return cmagic->comp_id;
-}
-
-int image_decomp(int comp, ulong load, ulong image_start, int type,
-                void *load_buf, void *image_buf, ulong image_len,
-                uint unc_len, ulong *load_end)
-{
-       int ret = -ENOSYS;
-
-       *load_end = load;
-       print_decomp_msg(comp, type, load == image_start);
-
-       /*
-        * Load the image to the right place, decompressing if needed. After
-        * this, image_len will be set to the number of uncompressed bytes
-        * loaded, ret will be non-zero on error.
-        */
-       switch (comp) {
-       case IH_COMP_NONE:
-               ret = 0;
-               if (load == image_start)
-                       break;
-               if (image_len <= unc_len)
-                       memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
-               else
-                       ret = -ENOSPC;
-               break;
-       case IH_COMP_GZIP:
-               if (!tools_build() && CONFIG_IS_ENABLED(GZIP))
-                       ret = gunzip(load_buf, unc_len, image_buf, &image_len);
-               break;
-       case IH_COMP_BZIP2:
-               if (!tools_build() && CONFIG_IS_ENABLED(BZIP2)) {
-                       uint size = unc_len;
-
-                       /*
-                        * If we've got less than 4 MB of malloc() space,
-                        * use slower decompression algorithm which requires
-                        * at most 2300 KB of memory.
-                        */
-                       ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
-                               image_buf, image_len, CONSERVE_MEMORY, 0);
-                       image_len = size;
-               }
-               break;
-       case IH_COMP_LZMA:
-               if (!tools_build() && CONFIG_IS_ENABLED(LZMA)) {
-                       SizeT lzma_len = unc_len;
-
-                       ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
-                                                      image_buf, image_len);
-                       image_len = lzma_len;
-               }
-               break;
-       case IH_COMP_LZO:
-               if (!tools_build() && CONFIG_IS_ENABLED(LZO)) {
-                       size_t size = unc_len;
-
-                       ret = lzop_decompress(image_buf, image_len, load_buf, &size);
-                       image_len = size;
-               }
-               break;
-       case IH_COMP_LZ4:
-               if (!tools_build() && CONFIG_IS_ENABLED(LZ4)) {
-                       size_t size = unc_len;
-
-                       ret = ulz4fn(image_buf, image_len, load_buf, &size);
-                       image_len = size;
-               }
-               break;
-       case IH_COMP_ZSTD:
-               if (!tools_build() && CONFIG_IS_ENABLED(ZSTD)) {
-                       struct abuf in, out;
-
-                       abuf_init_set(&in, image_buf, image_len);
-                       abuf_init_set(&in, load_buf, unc_len);
-                       ret = zstd_decompress(&in, &out);
-                       if (ret >= 0) {
-                               image_len = ret;
-                               ret = 0;
-                       }
-               }
-               break;
-       }
-       if (ret == -ENOSYS) {
-               printf("Unimplemented compression type %d\n", comp);
-               return ret;
-       }
-       if (ret)
-               return ret;
-
-       *load_end = load + image_len;
-
-       return 0;
-}
-
-const table_entry_t *get_table_entry(const table_entry_t *table, int id)
-{
-       for (; table->id >= 0; ++table) {
-               if (table->id == id)
-                       return table;
-       }
-       return NULL;
-}
-
-static const char *unknown_msg(enum ih_category category)
-{
-       static const char unknown_str[] = "Unknown ";
-       static char msg[30];
-
-       strcpy(msg, unknown_str);
-       strncat(msg, table_info[category].desc,
-               sizeof(msg) - sizeof(unknown_str));
-
-       return msg;
-}
-
-/**
- * genimg_get_cat_name - translate entry id to long name
- * @category: category to look up (enum ih_category)
- * @id: entry id to be translated
- *
- * This will scan the translation table trying to find the entry that matches
- * the given id.
- *
- * @return long entry name if translation succeeds; error string on failure
- */
-const char *genimg_get_cat_name(enum ih_category category, uint id)
-{
-       const table_entry_t *entry;
-
-       entry = get_table_entry(table_info[category].table, id);
-       if (!entry)
-               return unknown_msg(category);
-       return manual_reloc(entry->lname);
-}
-
-/**
- * genimg_get_cat_short_name - translate entry id to short name
- * @category: category to look up (enum ih_category)
- * @id: entry id to be translated
- *
- * This will scan the translation table trying to find the entry that matches
- * the given id.
- *
- * @return short entry name if translation succeeds; error string on failure
- */
-const char *genimg_get_cat_short_name(enum ih_category category, uint id)
-{
-       const table_entry_t *entry;
-
-       entry = get_table_entry(table_info[category].table, id);
-       if (!entry)
-               return unknown_msg(category);
-       return manual_reloc(entry->sname);
-}
-
-int genimg_get_cat_count(enum ih_category category)
-{
-       return table_info[category].count;
-}
-
-const char *genimg_get_cat_desc(enum ih_category category)
-{
-       return table_info[category].desc;
-}
-
-/**
- * genimg_cat_has_id - check whether category has entry id
- * @category: category to look up (enum ih_category)
- * @id: entry id to be checked
- *
- * This will scan the translation table trying to find the entry that matches
- * the given id.
- *
- * @return true if category has entry id; false if not
- */
-bool genimg_cat_has_id(enum ih_category category, uint id)
-{
-       if (get_table_entry(table_info[category].table, id))
-               return true;
-
-       return false;
-}
-
-/**
- * get_table_entry_name - translate entry id to long name
- * @table: pointer to a translation table for entries of a specific type
- * @msg: message to be returned when translation fails
- * @id: entry id to be translated
- *
- * get_table_entry_name() will go over translation table trying to find
- * entry that matches given id. If matching entry is found, its long
- * name is returned to the caller.
- *
- * returns:
- *     long entry name if translation succeeds
- *     msg otherwise
- */
-char *get_table_entry_name(const table_entry_t *table, char *msg, int id)
-{
-       table = get_table_entry(table, id);
-       if (!table)
-               return msg;
-       return manual_reloc(table->lname);
-}
-
-const char *genimg_get_os_name(uint8_t os)
-{
-       return (get_table_entry_name(uimage_os, "Unknown OS", os));
-}
-
-const char *genimg_get_arch_name(uint8_t arch)
-{
-       return (get_table_entry_name(uimage_arch, "Unknown Architecture",
-                                       arch));
-}
-
-const char *genimg_get_type_name(uint8_t type)
-{
-       return (get_table_entry_name(uimage_type, "Unknown Image", type));
-}
-
-const char *genimg_get_comp_name(uint8_t comp)
-{
-       return (get_table_entry_name(uimage_comp, "Unknown Compression",
-                                       comp));
-}
-
-static const char *genimg_get_short_name(const table_entry_t *table, int val)
-{
-       table = get_table_entry(table, val);
-       if (!table)
-               return "unknown";
-       return manual_reloc(table->sname);
-}
-
-const char *genimg_get_type_short_name(uint8_t type)
-{
-       return genimg_get_short_name(uimage_type, type);
-}
-
-const char *genimg_get_comp_short_name(uint8_t comp)
-{
-       return genimg_get_short_name(uimage_comp, comp);
-}
-
-const char *genimg_get_os_short_name(uint8_t os)
-{
-       return genimg_get_short_name(uimage_os, os);
-}
-
-const char *genimg_get_arch_short_name(uint8_t arch)
-{
-       return genimg_get_short_name(uimage_arch, arch);
-}
-
-/**
- * get_table_entry_id - translate short entry name to id
- * @table: pointer to a translation table for entries of a specific type
- * @table_name: to be used in case of error
- * @name: entry short name to be translated
- *
- * get_table_entry_id() will go over translation table trying to find
- * entry that matches given short name. If matching entry is found,
- * its id returned to the caller.
- *
- * returns:
- *     entry id if translation succeeds
- *     -1 otherwise
- */
-int get_table_entry_id(const table_entry_t *table,
-               const char *table_name, const char *name)
-{
-       const table_entry_t *t;
-
-       for (t = table; t->id >= 0; ++t) {
-               if (t->sname && !strcasecmp(manual_reloc(t->sname), name))
-                       return t->id;
-       }
-       debug("Invalid %s Type: %s\n", table_name, name);
-
-       return -1;
-}
-
-int genimg_get_os_id(const char *name)
-{
-       return (get_table_entry_id(uimage_os, "OS", name));
-}
-
-int genimg_get_arch_id(const char *name)
-{
-       return (get_table_entry_id(uimage_arch, "CPU", name));
-}
-
-int genimg_get_type_id(const char *name)
-{
-       return (get_table_entry_id(uimage_type, "Image", name));
-}
-
-int genimg_get_comp_id(const char *name)
-{
-       return (get_table_entry_id(uimage_comp, "Compression", name));
-}
index fa8f2a47ee36311b49ee95b008a4c6b66f45346d..71db02521b0b89794eb5776c3563125204e47353 100644 (file)
@@ -139,7 +139,7 @@ overview on the whole Android 10 boot process can be found at [8]_.
 C API for working with Android Boot Image format
 ------------------------------------------------
 
-.. kernel-doc:: common/image-android.c
+.. kernel-doc:: boot/image-android.c
    :internal:
 
 References
index 1bb2844913f4c0cac6f85378f75207f04e05cfd6..83a95ee4aa20ddb3e7fa442971aec92598bfdf77 100644 (file)
@@ -92,10 +92,10 @@ libs-y += common/init/
 
 # Special handling for a few options which support SPL/TPL
 ifeq ($(CONFIG_TPL_BUILD),y)
-libs-$(CONFIG_TPL_LIBCOMMON_SUPPORT) += common/ cmd/ env/
+libs-$(CONFIG_TPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
 libs-$(CONFIG_TPL_LIBGENERIC_SUPPORT) += lib/
 else
-libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ cmd/ env/
+libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
 libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
 ifdef CONFIG_SPL_FRAMEWORK
 libs-$(CONFIG_PARTITIONS) += disk/
index b45219e2c30c1455b34290639bd52bf63bcb5e6c..1763f44cac438a0ae1ca275f29fc10cd47e91870 100644 (file)
@@ -76,9 +76,9 @@ hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign
 
 hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include
 
-FIT_OBJS-y := fit_common.o fit_image.o image-host.o common/image-fit.o
-FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o common/image-fit-sig.o
-FIT_CIPHER_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := common/image-cipher.o
+FIT_OBJS-y := fit_common.o fit_image.o image-host.o boot/image-fit.o
+FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o boot/image-fit-sig.o
+FIT_CIPHER_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := boot/image-cipher.o
 
 # The following files are synced with upstream DTC.
 # Use synced versions from scripts/dtc/libfdt/.
@@ -106,14 +106,14 @@ dumpimage-mkimage-objs := aisimage.o \
                        $(FIT_OBJS-y) \
                        $(FIT_SIG_OBJS-y) \
                        $(FIT_CIPHER_OBJS-y) \
-                       common/fdt_region.o \
-                       common/bootm.o \
+                       boot/fdt_region.o \
+                       boot/bootm.o \
                        lib/crc32.o \
                        default_image.o \
                        lib/fdtdec_common.o \
                        lib/fdtdec.o \
-                       common/image.o \
-                       common/image-host.o \
+                       boot/image.o \
+                       boot/image-host.o \
                        imagetool.o \
                        imximage.o \
                        imx8image.o \
@@ -227,7 +227,7 @@ hostprogs-$(CONFIG_ARCH_OCTEON) += update_octeon_header
 update_octeon_header-objs := update_octeon_header.o lib/crc32.o
 
 hostprogs-y += fdtgrep
-fdtgrep-objs += $(LIBFDT_OBJS) common/fdt_region.o fdtgrep.o
+fdtgrep-objs += $(LIBFDT_OBJS) boot/fdt_region.o fdtgrep.o
 
 ifneq ($(TOOLS_ONLY),y)
 hostprogs-y += spl_size_limit
@@ -254,7 +254,7 @@ HOSTCFLAGS_sha512.o := -pedantic -DCONFIG_SHA512 -DCONFIG_SHA384
 quiet_cmd_wrap = WRAP    $@
 cmd_wrap = echo "\#include <../$(patsubst $(obj)/%,%,$@)>" >$@
 
-$(obj)/lib/%.c $(obj)/common/%.c $(obj)/env/%.c:
+$(obj)/boot/%.c $(obj)/common/%.c $(obj)/env/%.c $(obj)/lib/%.c:
        $(call cmd,wrap)
 
 clean-dirs := lib common