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