[PATCH v2 09/10] rockchip: binman: Add support for Falcon mode FIT images with TF-A+Linux

Alexey Charkov <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
Modern Rockchip SoCs such as RK3576 require TF-A to be running to provide
firmware services to the OS. To enable booting Linux in Falcon mode on
such SoCs, add a binman template for generation of FIT images containing
appropriately split TF-A and TEE binaries (as is currently done by binman
for U-boot proper images), externally provided Linux kernel and optionally
an initrd.

Any FDTs provided to the generator will be pre-patched with a /chosen
node containing an initrd load address and size (if an initrd is provided)
and a bootargs property containing the kernel command line (if provided),
so that the kernel can be booted directly without external preprocessing.

A config fragment rockchip-falcon.config can be used to enable Falcon
mode boot and the building of TF-A+Falcon with binman, e.g.:

  make nanopi-m5-rk3576_defconfig \
        rockchip-falcon.config

This will produce a FIT image u-boot-rockchip-falcon.itb containing TF-A,
TEE, Linux kernel and optionally an initrd, which can be flashed to UFS
and booted in Falcon mode.

This can also be combined with the existing rockchip-ramboot.config
fragment to obtain images suitable for booting from RAM, e.g.:

  make nanopi-m5-rk3576_defconfig \
        rockchip-falcon.config \
        rockchip-ramboot.config

The resulting images can be uploaded directly to RAM via Maskrom with no
storage or USB loader required, e.g.:

  rockusb download-sram u-boot-rockchip-usb471.bin
  rockusb download-ddr u-boot-rockchip-usb472-falcon.bin

Signed-off-by: Alexey Charkov <[email protected]>
---
 arch/arm/dts/rockchip-u-boot.dtsi     | 204 ++++++++++++++++++++++++++++------
 arch/arm/mach-rockchip/Kconfig        |  49 ++++++++
 board/rockchip/rockchip-falcon.config |   3 +
 3 files changed, 225 insertions(+), 31 deletions(-)

diff --git a/arch/arm/dts/rockchip-u-boot.dtsi b/arch/arm/dts/rockchip-u-boot.dtsi
index 4ba6a87e78ab..5e23ff761751 100644
--- a/arch/arm/dts/rockchip-u-boot.dtsi
+++ b/arch/arm/dts/rockchip-u-boot.dtsi
@@ -35,6 +35,16 @@
 #define HAS_FIT
 #endif
 
+#ifdef CONFIG_ROCKCHIP_FALCON_IMAGE
+/* Falcon-mode load addresses, relative to the SoC DRAM base. */
+#define FALCON_KERNEL_LOAD \
+	(CFG_SYS_SDRAM_BASE + CONFIG_ROCKCHIP_FALCON_KERNEL_LOAD)
+#define FALCON_FDT_LOAD \
+	(CFG_SYS_SDRAM_BASE + CONFIG_ROCKCHIP_FALCON_FDT_LOAD)
+#define FALCON_INITRD_LOAD \
+	(CFG_SYS_SDRAM_BASE + CONFIG_ROCKCHIP_FALCON_INITRD_LOAD)
+#endif
+
 / {
 	binman: binman {
 		multiple-images;
@@ -44,37 +54,13 @@
 #ifdef CONFIG_SPL
 &binman {
 #ifdef HAS_FIT
-	fit_template: template-1 {
-		type = "fit";
 #ifdef CONFIG_ARM64
-		description = "FIT image for U-Boot with bl31 (TF-A)";
-#else
-		description = "FIT image with OP-TEE";
-#endif
-		#address-cells = <1>;
-		fit,fdt-list = "of-list";
-		fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
-		fit,align = <512>;
+	/*
+	 * Shared ARM Trusted Firmware (BL31) and optional OP-TEE split-elf
+	 * images, reused by both the U-Boot and Falcon Linux FIT templates.
+	 */
+	fit_firmware_template: template-firmware {
 		images {
-			u-boot {
-				description = "U-Boot";
-				type = "standalone";
-				os = "u-boot";
-				arch = FIT_ARCH;
-				compression = FIT_UBOOT_COMP;
-				load = <CONFIG_TEXT_BASE>;
-				entry = <CONFIG_TEXT_BASE>;
-				u-boot-nodtb {
-					compress = FIT_UBOOT_COMP;
-				};
-#ifdef FIT_HASH_ALGO
-				hash {
-					algo = FIT_HASH_ALGO;
-				};
-#endif
-			};
-
-#ifdef CONFIG_ARM64
 			@atf-SEQ {
 				fit,operation = "split-elf";
 				description = "ARM Trusted Firmware";
@@ -114,7 +100,42 @@
 				};
 #endif
 			};
-#else /* !CONFIG_ARM64 */
+		};
+	};
+#endif /* CONFIG_ARM64 */
+
+	fit_template: template-1 {
+		type = "fit";
+#ifdef CONFIG_ARM64
+		description = "FIT image for U-Boot with bl31 (TF-A)";
+		insert-template = <&fit_firmware_template>;
+#else
+		description = "FIT image with OP-TEE";
+#endif
+		#address-cells = <1>;
+		fit,fdt-list = "of-list";
+		fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
+		fit,align = <512>;
+		images {
+			u-boot {
+				description = "U-Boot";
+				type = "standalone";
+				os = "u-boot";
+				arch = FIT_ARCH;
+				compression = FIT_UBOOT_COMP;
+				load = <CONFIG_TEXT_BASE>;
+				entry = <CONFIG_TEXT_BASE>;
+				u-boot-nodtb {
+					compress = FIT_UBOOT_COMP;
+				};
+#ifdef FIT_HASH_ALGO
+				hash {
+					algo = FIT_HASH_ALGO;
+				};
+#endif
+			};
+
+#ifndef CONFIG_ARM64
 			op-tee {
 				description = "OP-TEE";
 				type = "tee";
@@ -132,7 +153,7 @@
 				};
 #endif
 			};
-#endif /* CONFIG_ARM64 */
+#endif /* !CONFIG_ARM64 */
 
 			@fdt-SEQ {
 				description = "fdt-NAME";
@@ -161,6 +182,97 @@
 			};
 		};
 	};
+
+#ifdef CONFIG_ROCKCHIP_FALCON_IMAGE
+	fit_falcon_template: template-falcon {
+		type = "fit";
+		description = "FIT image for Falcon Linux with bl31 (TF-A)";
+		insert-template = <&fit_firmware_template>;
+		#address-cells = <1>;
+		fit,fdt-list = "of-list";
+		fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
+		fit,align = <512>;
+
+		images {
+			kernel {
+				description = "Linux kernel";
+				type = "kernel";
+				arch = FIT_ARCH;
+				os = "linux";
+				compression = FIT_UBOOT_COMP;
+				load = <FALCON_KERNEL_LOAD>;
+				entry = <FALCON_KERNEL_LOAD>;
+
+				linux-kernel {
+					compress = FIT_UBOOT_COMP;
+				};
+#ifdef FIT_HASH_ALGO
+				hash {
+					algo = FIT_HASH_ALGO;
+				};
+#endif
+			};
+
+			ramdisk {
+				description = "ramdisk";
+				type = "ramdisk";
+				arch = FIT_ARCH;
+				compression = "none";
+				load = <FALCON_INITRD_LOAD>;
+
+				linux-initrd {
+					optional;
+				};
+#ifdef FIT_HASH_ALGO
+				hash {
+					algo = FIT_HASH_ALGO;
+				};
+#endif
+			};
+
+			@fdt-SEQ {
+				description = "fdt-NAME";
+				type = "flat_dt";
+				arch = FIT_ARCH;
+				compression = "none";
+				load = <FALCON_FDT_LOAD>;
+#ifdef CONFIG_USE_BOOTARGS
+				fit,bootargs = CONFIG_BOOTARGS;
+#endif
+				fit,initrd = "ramdisk";
+#ifdef FIT_HASH_ALGO
+				hash {
+					algo = FIT_HASH_ALGO;
+				};
+#endif
+			};
+		};
+
+		configurations {
+			default = "@config-DEFAULT-SEQ";
+			@config-SEQ {
+				description = "NAME.dtb";
+				fit,firmware = "atf-1", "kernel", "ramdisk";
+				fit,loadables;
+				fit,compatible;
+				fdt = "fdt-SEQ";
+#ifdef FIT_HASH_ALGO
+				hash {
+					algo = FIT_HASH_ALGO;
+				};
+#endif
+			};
+		};
+	};
+
+	falcon-fit {
+		filename = "u-boot-rockchip-falcon.itb";
+
+		fit {
+			insert-template = <&fit_falcon_template>;
+		};
+	};
+#endif
 #endif /* HAS_FIT */
 
 	simple-bin {
@@ -260,6 +372,36 @@
 		};
 		};
 	};
+
+#ifdef CONFIG_ROCKCHIP_FALCON_IMAGE
+	simple-bin-usb472-falcon {
+		filename = "u-boot-rockchip-usb472-falcon.bin";
+		pad-byte = <0x00>;
+
+		u-boot-spl {
+		};
+
+		payload {
+			type = "section";
+			align = <CONFIG_SYS_CACHELINE_SIZE>;
+			/*
+			 * Must be named 'u-boot-any', unlike the non-Falcon
+			 * image which can call this 'fit': SPL declares
+			 * binman_sym(u_boot_any, image_pos) unconditionally, and
+			 * binman resolves that symbol against an entry of that
+			 * exact name or one called u-boot[-elf|-img|-nodtb].
+			 * Those only exist here by way of a U-Boot image inside
+			 * the FIT, which a Falcon FIT does not carry, so without
+			 * this name the symbol cannot be resolved and binman
+			 * fails. The type property is what selects the etype.
+			 */
+			u-boot-any {
+				type = "fit";
+				insert-template = <&fit_falcon_template>;
+			};
+		};
+	};
+#endif
 #endif /* CONFIG_ROCKCHIP_MASKROM_IMAGE */
 };
 #endif /* CONFIG_SPL */
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 1a2e7847c9e7..321afc0fbdf6 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -758,6 +758,55 @@ config ROCKCHIP_MASKROM_IMAGE
 	  Rockchip SoCs support maskrom mode boot over USB. Enable this
 	  option to produce maskrom mode boot images containing U-Boot.
 
+config ROCKCHIP_FALCON_IMAGE
+	bool "Build a Falcon mode image for Rockchip"
+	depends on SPL_OS_BOOT && ARM64 && SPL_ATF && SPL_FIT
+	help
+	  Enable this option to produce a FIT image which SPL can use to boot
+	  Linux directly via TF-A, bypassing U-Boot proper (Falcon mode).
+
+	  The image bundles TF-A (BL31), an optional OP-TEE, a Linux kernel
+	  and an optional initramfs, and its device trees are pre-patched with
+	  a /chosen node so that no further processing is needed before boot.
+	  The kernel is mandatory and must be supplied at build time with
+	  LINUX_KERNEL=/path/to/Image; pass LINUX_INITRD=/path/to/initramfs to
+	  include an initramfs as well.
+
+	  This only controls image generation. Say N to build a Falcon-capable
+	  SPL without bundling a kernel into the U-Boot image, for example when
+	  the OS payload is assembled and written to storage separately.
+
+config ROCKCHIP_FALCON_KERNEL_LOAD
+	hex "Falcon mode kernel load offset"
+	depends on ROCKCHIP_FALCON_IMAGE
+	default 0x10000000
+	help
+	  Offset from the start of DRAM at which the Falcon mode kernel is
+	  loaded and entered.
+
+	  All three Falcon mode load offsets have to be checked against the
+	  memory layout of the SoC and of the firmware in use. None of the
+	  three payloads may overlap each other, and none of them may overlap
+	  the regions BL31 and OP-TEE are linked to run from - note that
+	  binman splits their ELFs, so each of those occupies several regions
+	  rather than one contiguous range.
+
+config ROCKCHIP_FALCON_FDT_LOAD
+	hex "Falcon mode devicetree load offset"
+	depends on ROCKCHIP_FALCON_IMAGE
+	default 0x1c000000
+	help
+	  Offset from the start of DRAM at which the Falcon mode devicetree is
+	  loaded. The same constraints as for the kernel offset apply.
+
+config ROCKCHIP_FALCON_INITRD_LOAD
+	hex "Falcon mode initramfs load offset"
+	depends on ROCKCHIP_FALCON_IMAGE
+	default 0x1e000000
+	help
+	  Offset from the start of DRAM at which the Falcon mode initramfs is
+	  loaded. The same constraints as for the kernel offset apply.
+
 config LNX_KRNL_IMG_TEXT_OFFSET_BASE
 	default TEXT_BASE
 
diff --git a/board/rockchip/rockchip-falcon.config b/board/rockchip/rockchip-falcon.config
new file mode 100644
index 000000000000..ac903f16f46a
--- /dev/null
+++ b/board/rockchip/rockchip-falcon.config
@@ -0,0 +1,3 @@
+CONFIG_ROCKCHIP_FALCON_IMAGE=y
+CONFIG_SPL_OS_BOOT=y
+CONFIG_SYS_SPI_KERNEL_OFFS=0x0

-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.