[PATCH v2] arm64: zynqmp: Add support for u-boot.itb generation with ATF

Follow i.MX, Sunxi, RISC-V and Rockchip to generate u-boot.itb which includes U-Boot proper, ATF and DTBs in FIT format. ZynqMP supports FIT for quite a long time but with using out of tree solution. The patch is filling this gap.
Tested on zcu102, zcu104 and zcu100/Ultra96.
zcu100/Ultra96 v2.2 ATF build by: make DEBUG=0 ZYNQMP_CONSOLE=cadence1 RESET_TO_BL31=1 PLAT=zynqmp bl31
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
Changes in v2: - Exchange u-boot/atf in config section - Use default ATF baseaddr from mainline - Update commit message
Kconfig | 3 +- arch/arm/mach-zynqmp/mkimage_fit_atf.sh | 99 +++++++++++++++++++++++++ include/configs/xilinx_zynqmp.h | 6 +- 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100755 arch/arm/mach-zynqmp/mkimage_fit_atf.sh
diff --git a/Kconfig b/Kconfig index e22417ec4471..7efafffec0a4 100644 --- a/Kconfig +++ b/Kconfig @@ -253,7 +253,7 @@ config BUILD_TARGET default "u-boot-spl.kwb" if ARCH_MVEBU && SPL default "u-boot-elf.srec" if RCAR_GEN3 default "u-boot.itb" if SPL_LOAD_FIT && (ARCH_ROCKCHIP || \ - ARCH_SUNXI || RISCV) + ARCH_SUNXI || RISCV || ARCH_ZYNQMP) default "u-boot.kwb" if KIRKWOOD default "u-boot-with-spl.bin" if ARCH_AT91 && SPL_NAND_SUPPORT default "u-boot-with-spl.imx" if ARCH_MX6 && SPL @@ -481,6 +481,7 @@ config SPL_FIT_GENERATOR depends on SPL_FIT default "board/sunxi/mksunxi_fit_atf.sh" if SPL_LOAD_FIT && ARCH_SUNXI 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 default "arch/riscv/lib/mkimage_fit_opensbi.sh" if SPL_LOAD_FIT && RISCV help Specifies a (platform specific) script file to generate the FIT diff --git a/arch/arm/mach-zynqmp/mkimage_fit_atf.sh b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh new file mode 100755 index 000000000000..c50aba45ca5c --- /dev/null +++ b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh @@ -0,0 +1,99 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0+ +# +# script to generate FIT image source for Xilinx ZynqMP boards with +# ARM Trusted Firmware and multiple device trees (given on the command line) +# +# usage: $0 <dt_name> [<dt_name> [<dt_name] ...] + +BL33="u-boot-nodtb.bin" +[ -z "$BL31" ] && BL31="bl31.bin" +[ -z "$ATF_LOAD_ADDR" ] && ATF_LOAD_ADDR="0xfffea000" +[ -z "$BL33_LOAD_ADDR" ] && BL33_LOAD_ADDR="0x8000000" + +if [ ! -f $BL31 ]; then + echo "ERROR: BL31 file $BL31 NOT found" >&2 +else + echo "$BL31 size: " >&2 + ls -lct $BL31 | awk '{print $5}' >&2 +fi + + + +cat << __HEADER_EOF +/dts-v1/; + +/ { + description = "Configuration to load ATF before U-Boot"; + + images { + uboot { + description = "U-Boot (64-bit)"; + data = /incbin/("$BL33"); + type = "firmware"; + os = "u-boot"; + arch = "arm64"; + compression = "none"; + load = <$BL33_LOAD_ADDR>; + hash { + algo = "md5"; + }; + }; + atf { + description = "ARM Trusted Firmware"; + data = /incbin/("$BL31"); + type = "firmware"; + os = "arm-trusted-firmware"; + arch = "arm64"; + compression = "none"; + load = <$ATF_LOAD_ADDR>; + entry = <$ATF_LOAD_ADDR>; + hash { + algo = "md5"; + }; + }; +__HEADER_EOF + +cnt=1 +for dtname in $* +do + cat << __FDT_IMAGE_EOF + fdt_$cnt { + description = "$(basename $dtname .dtb)"; + data = /incbin/("$dtname"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + hash { + algo = "md5"; + }; + }; +__FDT_IMAGE_EOF +cnt=$((cnt+1)) +done + +cat << __CONF_HEADER_EOF + }; + configurations { + default = "config_1"; + +__CONF_HEADER_EOF + +cnt=1 +for dtname in $* +do +cat << __CONF_SECTION1_EOF + config_$cnt { + description = "$(basename $dtname .dtb)"; + firmware = "atf"; + loadables = "uboot"; + fdt = "fdt_$cnt"; + }; +__CONF_SECTION1_EOF +cnt=$((cnt+1)) +done + +cat << __ITS_EOF + }; +}; +__ITS_EOF diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index ee1ceebf1291..e7eb8dbfcb45 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -243,7 +243,11 @@ # define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 0 /* unused */ # define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS 0 /* unused */ # define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 0 /* unused */ -# define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" +# if defined(CONFIG_SPL_LOAD_FIT) +# define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.itb" +# else +# define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" +# endif #endif
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_DFU)

On Thu, Dec 05, 2019 at 09:46:57AM +0100, Michal Simek wrote:
Follow i.MX, Sunxi, RISC-V and Rockchip to generate u-boot.itb which includes U-Boot proper, ATF and DTBs in FIT format. ZynqMP supports FIT for quite a long time but with using out of tree solution. The patch is filling this gap.
Tested on zcu102, zcu104 and zcu100/Ultra96.
zcu100/Ultra96 v2.2 ATF build by: make DEBUG=0 ZYNQMP_CONSOLE=cadence1 RESET_TO_BL31=1 PLAT=zynqmp bl31
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
- Exchange u-boot/atf in config section
- Use default ATF baseaddr from mainline
- Update commit message
Kconfig | 3 +- arch/arm/mach-zynqmp/mkimage_fit_atf.sh | 99 +++++++++++++++++++++++++
My only complaint here is adding and N'th version of mkimage_fit_atf.sh that varies seemingly only in addresses. Can we not abstract this enough to make it for everyone to use and pass in the needed values?

On 05. 12. 19 15:33, Tom Rini wrote:
On Thu, Dec 05, 2019 at 09:46:57AM +0100, Michal Simek wrote:
Follow i.MX, Sunxi, RISC-V and Rockchip to generate u-boot.itb which includes U-Boot proper, ATF and DTBs in FIT format. ZynqMP supports FIT for quite a long time but with using out of tree solution. The patch is filling this gap.
Tested on zcu102, zcu104 and zcu100/Ultra96.
zcu100/Ultra96 v2.2 ATF build by: make DEBUG=0 ZYNQMP_CONSOLE=cadence1 RESET_TO_BL31=1 PLAT=zynqmp bl31
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
- Exchange u-boot/atf in config section
- Use default ATF baseaddr from mainline
- Update commit message
Kconfig | 3 +- arch/arm/mach-zynqmp/mkimage_fit_atf.sh | 99 +++++++++++++++++++++++++
My only complaint here is adding and N'th version of mkimage_fit_atf.sh that varies seemingly only in addresses. Can we not abstract this enough to make it for everyone to use and pass in the needed values?
First of all I will be sending v3 because of other things I found.
Adding more folks to this.
I have went through all versions and here is sort of stat:
board/sunxi/mksunxi_fit_atf.sh - firmware is uboot, atf loadables (not standard)
board/theobroma-systems/puma_rk3399/fit_spl_atf.sh - license present atf, uboot, pmufw (only present here)
arch/arm/mach-rockchip/make_fit_atf.py - python (only one) and read addresses from elfs
arch/arm/mach-rockchip/fit_spl_optee.sh - firmware is tee(no ATF)
arch/riscv/lib/mkimage_fit_opensbi.sh - reads stuff from .config and also handles non DT case
arch/arm/mach-imx/mkimage_fit_atf.sh - optee, atf, incorrect dt nodes names
And of course this one.
-------------------------------
I think the key point here is to start talk about how this should be done. Language? One is python others are shell scripts.
Should it stop when ATF/TEE is not found?
What file to read to get information from u-boot? .config or include/generated/autoconf.h?
Read information about locations from ELFs?
Should we handle non DT case? Yes?
Move just DT generation to common location and keep VARs, file checking in board/arch scripts?
Thanks, Michal

On Mon, Dec 09, 2019 at 03:21:02PM +0100, Michal Simek wrote:
On 05. 12. 19 15:33, Tom Rini wrote:
On Thu, Dec 05, 2019 at 09:46:57AM +0100, Michal Simek wrote:
Follow i.MX, Sunxi, RISC-V and Rockchip to generate u-boot.itb which includes U-Boot proper, ATF and DTBs in FIT format. ZynqMP supports FIT for quite a long time but with using out of tree solution. The patch is filling this gap.
Tested on zcu102, zcu104 and zcu100/Ultra96.
zcu100/Ultra96 v2.2 ATF build by: make DEBUG=0 ZYNQMP_CONSOLE=cadence1 RESET_TO_BL31=1 PLAT=zynqmp bl31
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
- Exchange u-boot/atf in config section
- Use default ATF baseaddr from mainline
- Update commit message
Kconfig | 3 +- arch/arm/mach-zynqmp/mkimage_fit_atf.sh | 99 +++++++++++++++++++++++++
My only complaint here is adding and N'th version of mkimage_fit_atf.sh that varies seemingly only in addresses. Can we not abstract this enough to make it for everyone to use and pass in the needed values?
First of all I will be sending v3 because of other things I found.
Adding more folks to this.
I have went through all versions and here is sort of stat:
board/sunxi/mksunxi_fit_atf.sh - firmware is uboot, atf loadables (not standard)
board/theobroma-systems/puma_rk3399/fit_spl_atf.sh - license present atf, uboot, pmufw (only present here)
arch/arm/mach-rockchip/make_fit_atf.py - python (only one) and read addresses from elfs
arch/arm/mach-rockchip/fit_spl_optee.sh - firmware is tee(no ATF)
arch/riscv/lib/mkimage_fit_opensbi.sh - reads stuff from .config and also handles non DT case
arch/arm/mach-imx/mkimage_fit_atf.sh - optee, atf, incorrect dt nodes names
And of course this one.
Thanks for looking more here.
I think the key point here is to start talk about how this should be done. Language? One is python others are shell scripts.
I don't have a hard preference here. I think the reason we have one in Python is for ease of working with ELF. Restrictions / issues like that probably mean it would be best to make sure we pick a language that allows for peeking at ELFs but I have not confirmed if we could easily re-do the rockchip python tool in shell by using a standard tool (objdump or similar from binutils, so we'll certainly have it).
Should it stop when ATF/TEE is not found?
For CI it must non-fatally complete, but should also be verbose in that the resulting binary is non-functional.
What file to read to get information from u-boot? .config or include/generated/autoconf.h?
Honestly? I'd like to start looking at something better if we can here as these are not really user-configurable values, but system values. Some property under a -u-boot.dtsi file?
Read information about locations from ELFs?
Should we handle non DT case? Yes?
Sorry, non-DT case in this instance meaning what? We're talking about FIT and FIT uses a DT.
Move just DT generation to common location and keep VARs, file checking in board/arch scripts?
High level, this sounds right. Thanks!

On 09. 12. 19 16:49, Tom Rini wrote:
On Mon, Dec 09, 2019 at 03:21:02PM +0100, Michal Simek wrote:
On 05. 12. 19 15:33, Tom Rini wrote:
On Thu, Dec 05, 2019 at 09:46:57AM +0100, Michal Simek wrote:
Follow i.MX, Sunxi, RISC-V and Rockchip to generate u-boot.itb which includes U-Boot proper, ATF and DTBs in FIT format. ZynqMP supports FIT for quite a long time but with using out of tree solution. The patch is filling this gap.
Tested on zcu102, zcu104 and zcu100/Ultra96.
zcu100/Ultra96 v2.2 ATF build by: make DEBUG=0 ZYNQMP_CONSOLE=cadence1 RESET_TO_BL31=1 PLAT=zynqmp bl31
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
- Exchange u-boot/atf in config section
- Use default ATF baseaddr from mainline
- Update commit message
Kconfig | 3 +- arch/arm/mach-zynqmp/mkimage_fit_atf.sh | 99 +++++++++++++++++++++++++
My only complaint here is adding and N'th version of mkimage_fit_atf.sh that varies seemingly only in addresses. Can we not abstract this enough to make it for everyone to use and pass in the needed values?
First of all I will be sending v3 because of other things I found.
Adding more folks to this.
I have went through all versions and here is sort of stat:
board/sunxi/mksunxi_fit_atf.sh - firmware is uboot, atf loadables (not standard)
board/theobroma-systems/puma_rk3399/fit_spl_atf.sh - license present atf, uboot, pmufw (only present here)
arch/arm/mach-rockchip/make_fit_atf.py - python (only one) and read addresses from elfs
arch/arm/mach-rockchip/fit_spl_optee.sh - firmware is tee(no ATF)
arch/riscv/lib/mkimage_fit_opensbi.sh - reads stuff from .config and also handles non DT case
arch/arm/mach-imx/mkimage_fit_atf.sh - optee, atf, incorrect dt nodes names
And of course this one.
Thanks for looking more here.
I think the key point here is to start talk about how this should be done. Language? One is python others are shell scripts.
I don't have a hard preference here. I think the reason we have one in Python is for ease of working with ELF. Restrictions / issues like that probably mean it would be best to make sure we pick a language that allows for peeking at ELFs but I have not confirmed if we could easily re-do the rockchip python tool in shell by using a standard tool (objdump or similar from binutils, so we'll certainly have it).
I expect that all addresses are just entry points of these elfs It means something like this should be enough. readelf -l bl31.elf | awk '/Entry point/ { print $3 }'
Should it stop when ATF/TEE is not found?
For CI it must non-fatally complete, but should also be verbose in that the resulting binary is non-functional.
ok.
What file to read to get information from u-boot? .config or include/generated/autoconf.h?
Honestly? I'd like to start looking at something better if we can here as these are not really user-configurable values, but system values. Some property under a -u-boot.dtsi file?
I still have one ancient branch to get rid of all u-boot,dm* variables from nodes and move them to chosen node where they should be. Can you please elaborate on this more?
Read information about locations from ELFs?
Should we handle non DT case? Yes?
Sorry, non-DT case in this instance meaning what? We're talking about FIT and FIT uses a DT.
With OF_BOARD configurations where DT can be stored somewhere else there could be use cases that you want to have FIT without DT.
Move just DT generation to common location and keep VARs, file checking in board/arch scripts?
High level, this sounds right. Thanks!
I would like to get more feedback from others to agreed how this should be done before anybody invest time for doing it.
Thanks, Michal

On Tue, Dec 10, 2019 at 01:03:29PM +0100, Michal Simek wrote:
On 09. 12. 19 16:49, Tom Rini wrote:
On Mon, Dec 09, 2019 at 03:21:02PM +0100, Michal Simek wrote:
On 05. 12. 19 15:33, Tom Rini wrote:
On Thu, Dec 05, 2019 at 09:46:57AM +0100, Michal Simek wrote:
Follow i.MX, Sunxi, RISC-V and Rockchip to generate u-boot.itb which includes U-Boot proper, ATF and DTBs in FIT format. ZynqMP supports FIT for quite a long time but with using out of tree solution. The patch is filling this gap.
Tested on zcu102, zcu104 and zcu100/Ultra96.
zcu100/Ultra96 v2.2 ATF build by: make DEBUG=0 ZYNQMP_CONSOLE=cadence1 RESET_TO_BL31=1 PLAT=zynqmp bl31
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
- Exchange u-boot/atf in config section
- Use default ATF baseaddr from mainline
- Update commit message
Kconfig | 3 +- arch/arm/mach-zynqmp/mkimage_fit_atf.sh | 99 +++++++++++++++++++++++++
My only complaint here is adding and N'th version of mkimage_fit_atf.sh that varies seemingly only in addresses. Can we not abstract this enough to make it for everyone to use and pass in the needed values?
First of all I will be sending v3 because of other things I found.
Adding more folks to this.
I have went through all versions and here is sort of stat:
board/sunxi/mksunxi_fit_atf.sh - firmware is uboot, atf loadables (not standard)
board/theobroma-systems/puma_rk3399/fit_spl_atf.sh - license present atf, uboot, pmufw (only present here)
arch/arm/mach-rockchip/make_fit_atf.py - python (only one) and read addresses from elfs
arch/arm/mach-rockchip/fit_spl_optee.sh - firmware is tee(no ATF)
arch/riscv/lib/mkimage_fit_opensbi.sh - reads stuff from .config and also handles non DT case
arch/arm/mach-imx/mkimage_fit_atf.sh - optee, atf, incorrect dt nodes names
And of course this one.
Thanks for looking more here.
I think the key point here is to start talk about how this should be done. Language? One is python others are shell scripts.
I don't have a hard preference here. I think the reason we have one in Python is for ease of working with ELF. Restrictions / issues like that probably mean it would be best to make sure we pick a language that allows for peeking at ELFs but I have not confirmed if we could easily re-do the rockchip python tool in shell by using a standard tool (objdump or similar from binutils, so we'll certainly have it).
I expect that all addresses are just entry points of these elfs It means something like this should be enough. readelf -l bl31.elf | awk '/Entry point/ { print $3 }'
OK. Then we should probably stick to shell.
Should it stop when ATF/TEE is not found?
For CI it must non-fatally complete, but should also be verbose in that the resulting binary is non-functional.
ok.
What file to read to get information from u-boot? .config or include/generated/autoconf.h?
Honestly? I'd like to start looking at something better if we can here as these are not really user-configurable values, but system values. Some property under a -u-boot.dtsi file?
I still have one ancient branch to get rid of all u-boot,dm* variables from nodes and move them to chosen node where they should be. Can you please elaborate on this more?
Well, it's been pointed out before, and I agree, that a lot of things we have had historically in CONFIG_xxx symbols are things that just aren't appropriate for Kconfig (users shouldn't change them, putting N default values in Kconfig is ugly, etc). While devicetree-the-in-kernel-file is to describe the hardware, devicetree-the-syntax is something we use for other things (FIT images) and other projects take even farther. So I've been thinking that devicetree-the-syntax seems like a good way to handle this particular problem. Where it all goes, I don't know.
participants (2)
-
Michal Simek
-
Tom Rini