All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] board: dragonboard410c: Load U-Boot directly without LK
@ 2021-07-07  9:06 Stephan Gerhold
  2021-07-10 19:07 ` Ramon Fried
  2021-07-24 20:39 ` Tom Rini
  0 siblings, 2 replies; 4+ messages in thread
From: Stephan Gerhold @ 2021-07-07  9:06 UTC (permalink / raw)
  To: u-boot
  Cc: Stephan Gerhold, Ramon Fried, Jorge Ramirez-Ortiz, Nicolas Dechesne

At the moment the U-Boot port for the DragonBoard 410c is designed
to be loaded as an Android boot image after Qualcomm's Little Kernel (LK)
bootloader. This is simple to set up but LK is redundant in this case,
since everything done by LK can be also done directly by U-Boot.

Dropping LK entirely has at least the following advantages:
  - Easier installation/board code (no need for Android boot images)
  - (Slightly) faster boot
  - Boot directly in 64-bit without a round trip to 32-bit for LK

So far this was not possible yet because of unsolved problems:

  1. Signing tool: The firmware expects a "signed" ELF image with extra
     (Qualcomm-specific) ELF headers, usually used for secure boot.
     The DragonBoard 410c does not have secure boot by default but the
     extra ELF headers are still required.

  2. PSCI bug: There seems to be a bug in the PSCI implementation
     (part of the TrustZone/tz firmware) that causes all other CPU cores
     to be started in 32-bit mode if LK is missing in the boot chain.
     This causes Linux to hang early during boot.

There is a solution for both problems now:

  1. qtestsign (https://github.com/msm8916-mainline/qtestsign)
     can be used as a "signing" tool for U-Boot and other firmware.

  2. A workaround for the "PSCI bug" is to execute the TZ syscall when
     entering U-Boot. That way PSCI is made aware of the 64-bit switch
     and starts all other CPU cores in 64-bit mode as well.

Simplify the dragonboard410c board by removing all the extra code that
is only used to build an Android boot image that can be loaded by LK.
This allows dropping the custom linker script, special image magic,
as well as most of the special build/installation instructions.

CONFIG_REMAKE_ELF is used to build a new ELF image that has both U-Boot
and the appended DTB combined. The resulting u-boot.elf can then be
passed to the "signing" tool (e.g. qtestsign).

The PSCI workaround is placed in the "boot0" hook that is enabled
with CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK. The extra check for EL1 allows
compatibility with custom firmware that enters U-Boot in EL2 or EL3,
e.g. qhypstub (https://github.com/msm8916-mainline/qhypstub).

As a first step these changes apply only to DragonBoard410c.
Similar changes could likely also work for the DragonBoard 820c.

Note that removing LK wouldn't be possible that easily without a lot of
work already done three years ago by Ramon Fried. A lot of missing
initialization, pinctrl etc was already added back then even though
it was not strictly needed yet.

Cc: Ramon Fried <rfried.dev@gmail.com>
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---

Related RFC with even more detailed explanations:
https://lore.kernel.org/u-boot/YN2F1c926HFF+JA2@gerhold.net/

In my tests both U-Boot and Linux are fully functional with this patch.
However, I would appreciate further testing, since my testing does
likely not represent a typical usage scenario for the DragonBoard 410c.

When testing, please pick the following pending patch additionally:
  https://lore.kernel.org/u-boot/20210705121847.48432-1-stephan@gerhold.net/
on top of u-boot/master.

---
 arch/arm/mach-snapdragon/Kconfig              |   1 +
 arch/arm/mach-snapdragon/include/mach/boot0.h |  54 ++++++++
 board/qualcomm/dragonboard410c/MAINTAINERS    |   1 +
 board/qualcomm/dragonboard410c/Makefile       |   2 -
 .../dragonboard410c/dragonboard410c.c         |  13 --
 board/qualcomm/dragonboard410c/head.S         |  33 -----
 .../qualcomm/dragonboard410c/lowlevel_init.S  |  27 ----
 board/qualcomm/dragonboard410c/readme.txt     |  73 +----------
 board/qualcomm/dragonboard410c/u-boot.lds     | 118 ------------------
 configs/dragonboard410c_defconfig             |   2 +-
 doc/board/index.rst                           |   1 +
 doc/board/qualcomm/dragonboard410c.rst        |  45 +++++++
 doc/board/qualcomm/index.rst                  |   9 ++
 include/configs/dragonboard410c.h             |   3 +
 14 files changed, 120 insertions(+), 262 deletions(-)
 create mode 100644 arch/arm/mach-snapdragon/include/mach/boot0.h
 delete mode 100644 board/qualcomm/dragonboard410c/head.S
 delete mode 100644 board/qualcomm/dragonboard410c/lowlevel_init.S
 delete mode 100644 board/qualcomm/dragonboard410c/u-boot.lds
 create mode 100644 doc/board/qualcomm/dragonboard410c.rst
 create mode 100644 doc/board/qualcomm/index.rst

diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index e562d693c6..0ec74fa5d3 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -15,6 +15,7 @@ choice
 config TARGET_DRAGONBOARD410C
 	bool "96Boards Dragonboard 410C"
 	select BOARD_LATE_INIT
+	select ENABLE_ARM_SOC_BOOT0_HOOK
 	help
 	  Support for 96Boards Dragonboard 410C. This board complies with
 	  96Board Open Platform Specifications. Features:
diff --git a/arch/arm/mach-snapdragon/include/mach/boot0.h b/arch/arm/mach-snapdragon/include/mach/boot0.h
new file mode 100644
index 0000000000..953cccad79
--- /dev/null
+++ b/arch/arm/mach-snapdragon/include/mach/boot0.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Workaround for "PSCI bug" on DragonBoard 410c
+ * Copyright (C) 2021 Stephan Gerhold <stephan@gerhold.net>
+ *
+ * Syscall parameters taken from Qualcomm's LK fork (scm.h):
+ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+ *
+ * The PSCI implementation in the TrustZone/tz firmware on DragonBoard 410c has
+ * a bug that starts all other CPU cores in 32-bit mode unless the TZ syscall
+ * that switches from 32-bit to 64-bit mode is executed at least once.
+ *
+ * Normally this happens inside Qualcomm's LK bootloader which runs in 32-bit
+ * mode and uses the TZ syscall to boot a kernel in 64-bit mode. However, if
+ * U-Boot is installed to the "aboot" partition (replacing LK) the switch to
+ * 64-bit mode never happens since U-Boot is already running in 64-bit mode.
+ *
+ * A workaround for this "PSCI bug" is to execute the TZ syscall when entering
+ * U-Boot. That way PSCI is made aware of the 64-bit switch and starts all other
+ * CPU cores in 64-bit mode as well.
+ */
+#include <linux/arm-smccc.h>
+
+#define ARM_SMCCC_SIP32_FAST_CALL \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_SIP, 0)
+
+	/*
+	 * U-Boot might be started in EL2 or EL3 with custom firmware.
+	 * In that case, we assume that the workaround is not necessary or is
+	 * handled already by the alternative firmware. Using the syscall in EL2
+	 * would demote U-Boot to EL1; in EL3 it would probably just crash.
+	 */
+	mrs	x0, CurrentEL
+	cmp	x0, #(1 << 2)	/* EL1 */
+	bne	reset
+
+	/* Prepare TZ syscall parameters */
+	mov	x0, #ARM_SMCCC_SIP32_FAST_CALL
+	movk	x0, #0x10f	/* SCM_SVC_MILESTONE_CMD_ID */
+	mov	x1, #0x12	/* MAKE_SCM_ARGS(0x2, SMC_PARAM_TYPE_BUFFER_READ) */
+	adr	x2, el1_system_param
+	mov	x3, el1_system_param_end - el1_system_param
+
+	/* Switch PSCI to 64-bit mode. Resets CPU and returns at el1_elr */
+	smc	#0
+
+	/* Something went wrong, perhaps PSCI is already in 64-bit mode? */
+	b	reset
+
+	.align	3
+el1_system_param:
+	.quad	0, 0, 0, 0, 0, 0, 0, 0, 0	/* el1_x0-x8 */
+	.quad	reset				/* el1_elr */
+el1_system_param_end:
diff --git a/board/qualcomm/dragonboard410c/MAINTAINERS b/board/qualcomm/dragonboard410c/MAINTAINERS
index 83448f5c13..e78f5b2d64 100644
--- a/board/qualcomm/dragonboard410c/MAINTAINERS
+++ b/board/qualcomm/dragonboard410c/MAINTAINERS
@@ -4,3 +4,4 @@ S:	Maintained
 F:	board/qualcomm/dragonboard410c/
 F:	include/configs/dragonboard410c.h
 F:	configs/dragonboard410c_defconfig
+F:	doc/board/qualcomm/dragonboard410c.rst
diff --git a/board/qualcomm/dragonboard410c/Makefile b/board/qualcomm/dragonboard410c/Makefile
index 9b452041f4..1b99c8b0ef 100644
--- a/board/qualcomm/dragonboard410c/Makefile
+++ b/board/qualcomm/dragonboard410c/Makefile
@@ -3,5 +3,3 @@
 # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
 
 obj-y	:= dragonboard410c.o
-obj-y	+= lowlevel_init.o
-extra-y += head.o
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
index 0d282de958..3b71881cac 100644
--- a/board/qualcomm/dragonboard410c/dragonboard410c.c
+++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
@@ -22,19 +22,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* pointer to the device tree ammended by the firmware */
-extern void *fw_dtb;
-
-void *board_fdt_blob_setup(void)
-{
-	if (fdt_magic(fw_dtb) != FDT_MAGIC) {
-		printf("Firmware provided invalid dtb!\n");
-		return NULL;
-	}
-
-	return fw_dtb;
-}
-
 int dram_init(void)
 {
 	gd->ram_size = PHYS_SDRAM_1_SIZE;
diff --git a/board/qualcomm/dragonboard410c/head.S b/board/qualcomm/dragonboard410c/head.S
deleted file mode 100644
index 33e9d305f9..0000000000
--- a/board/qualcomm/dragonboard410c/head.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * ARM64 header for proper chain-loading with Little Kernel.
- *
- * Little Kernel shipped with Dragonboard410C boots standard Linux images for
- * ARM64. This file adds header that is required to boot U-Boot properly.
- *
- * For details see:
- * https://www.kernel.org/doc/Documentation/arm64/booting.txt
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
- */
-
-#include <config.h>
-
-.global _arm64_header
-_arm64_header:
-	b _start
-	.word 0
-	/* Image load offset from start of RAM, little-endian */
-	.quad   CONFIG_SYS_TEXT_BASE-PHYS_SDRAM_1
-	/* Effective size of kernel image, little-endian */
-	.quad   0 /* 0x60000 - ignored */
-	/* Informative flags, little-endian */
-	.quad   0
-	.quad   0                               /* reserved */
-	.quad   0                               /* reserved */
-	.quad   0                               /* reserved */
-	.byte   0x41                            /* Magic number, "ARM\x64" */
-	.byte   0x52
-	.byte   0x4d
-	.byte   0x64
-	.word   0                               /* reserved */
diff --git a/board/qualcomm/dragonboard410c/lowlevel_init.S b/board/qualcomm/dragonboard410c/lowlevel_init.S
deleted file mode 100644
index 762fed5617..0000000000
--- a/board/qualcomm/dragonboard410c/lowlevel_init.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2016
- * Cédric Schieli <cschieli@gmail.com>
- */
-
-#include <config.h>
-
-.align 8
-.global fw_dtb
-fw_dtb:
-	.dword 0x0
-
-/*
- * Routine: save_boot_params (called after reset from start.S)
- * Description: save ATAG/FDT address provided by the firmware at boot time
- */
-
-.global save_boot_params
-save_boot_params:
-
-	/* The firmware provided ATAG/FDT address can be found in r2/x0 */
-	adr	x8, fw_dtb
-	str	x0, [x8]
-
-	/* Returns */
-	b	save_boot_params_ret
diff --git a/board/qualcomm/dragonboard410c/readme.txt b/board/qualcomm/dragonboard410c/readme.txt
index a90d0f52e7..dfdb299fb7 100644
--- a/board/qualcomm/dragonboard410c/readme.txt
+++ b/board/qualcomm/dragonboard410c/readme.txt
@@ -1,69 +1,6 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+Documentation for DragonBoard 410c is now located at:
+    doc/board/qualcomm/dragonboard410c.rst
 
-Build & Run instructions:
-
-1) Install mkbootimg and dtbTool from
-   git://codeaurora.org/quic/kernel/skales (15ece94f09 worked for me)
-2) Setup CROSS_COMPILE to aarch64 compiler
-3) make dragonboard410c_config
-4) make
-5) generate fake, empty ramdisk (can have 0 bytes)
-$ touch rd
-
-6) Generate qualcomm device tree table with dtbTool [1]
-$ dtbTool -o dt.img arch/arm/dts
-
-7) Generate Android boot image with mkbootimg [2]:
-$ mkbootimg --kernel=u-boot-dtb.bin --output=u-boot.img --dt=dt.img  \
-  --pagesize 2048 --base 0x80000000 --ramdisk=rd --cmdline=""
-
-8) Enter fastboot (reboot board with vol- button pressed)
-
-9) Boot it:
-$ fastboot boot u-boot.img
-or flash as kernel:
-$ fastboot flash boot u-boot.img
-$ fastboot reboot
-
-
-What is working:
-- UART
-- GPIO (SoC)
-- SD
-- eMMC
-- Reset
-- USB in EHCI mode (usb starts does switch device->host, usb stop does the opposite)
-- PMIC GPIOS (but not in generic subsystem)
-- PMIC "special" buttons (power, vol-)
-
-What is not working / known bugs:
-- SDHCI is slow (~2.5MiB/s for SD and eMMC)
-
-[1] To boot any kernel image, Little Kernel requires valid device tree for the
-platform it runs on. dtbTool creates device tree table that Little Kernel scans.
-Later on proper device tree is passed to next boot stage.
-Full device tree is not required to boot u-boot. Enough would be:
-/dts-v1/;
-
-/ {
-	model = "Qualcomm Technologies, Inc. Dragonboard 410c";
-	compatible = "qcom,dragonboard", "qcom,apq8016-sbc";
-	qcom,msm-id = <0xce 0x0 0xf8 0x0 0xf9 0x0 0xfa 0x0 0xf7 0x0>;
-	qcom,board-id = <0x10018 0x0>;
-	#address-cells = <0x2>;
-	#size-cells = <0x2>;
-	chosen { };
-	aliases { };
-
-	memory {
-		device_type = "memory";
-		reg = <0 0x80000000 0 0x3da00000>;
-	};
-};
-
-but for simplicity (and because size of image is not that critical) we use
-existing Qualcomm device trees.
-
-[2] Note that ramdisk is required, even if it is unused.
+Note that the installation method has changed: U-Boot is now installed into the
+"aboot" partition (replacing Little Kernel/LK). It is no longer packaged into
+an Android boot image and loaded through Qualcomm's LK bootloader.
diff --git a/board/qualcomm/dragonboard410c/u-boot.lds b/board/qualcomm/dragonboard410c/u-boot.lds
deleted file mode 100644
index fc1bba8cf0..0000000000
--- a/board/qualcomm/dragonboard410c/u-boot.lds
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Override linker script for fastboot-readable images
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
- *
- * Based on arch/arm/cpu/armv8/u-boot.lds (Just add header)
- */
-
-OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
-OUTPUT_ARCH(aarch64)
-ENTRY(_arm64_header)
-SECTIONS
-{
-	. = 0x00000000;
-
-	. = ALIGN(8);
-	.text :
-	{
-		*(.__image_copy_start)
-		board/qualcomm/dragonboard410c/head.o (.text*)
-		CPUDIR/start.o (.text*)
-	}
-
-	/* This needs to come before *(.text*) */
-	.efi_runtime : {
-                __efi_runtime_start = .;
-		*(.text.efi_runtime*)
-		*(.rodata.efi_runtime*)
-		*(.data.efi_runtime*)
-                __efi_runtime_stop = .;
-	}
-
-	.text_rest :
-	{
-		*(.text*)
-	}
-
-	. = ALIGN(8);
-	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
-	. = ALIGN(8);
-	.data : {
-		*(.data*)
-	}
-
-	. = ALIGN(8);
-
-	. = .;
-
-	. = ALIGN(8);
-	.u_boot_list : {
-		KEEP(*(SORT(.u_boot_list*)));
-	}
-
-	. = ALIGN(8);
-
-	.efi_runtime : {
-                __efi_runtime_start = .;
-		*(efi_runtime_text)
-		*(efi_runtime_data)
-                __efi_runtime_stop = .;
-	}
-
-	.efi_runtime_rel : {
-                __efi_runtime_rel_start = .;
-		*(.rel*.efi_runtime)
-		*(.rel*.efi_runtime.*)
-                __efi_runtime_rel_stop = .;
-	}
-
-	. = ALIGN(8);
-
-	.image_copy_end :
-	{
-		*(.__image_copy_end)
-	}
-
-	. = ALIGN(8);
-
-	.rel_dyn_start :
-	{
-		*(.__rel_dyn_start)
-	}
-
-	.rela.dyn : {
-		*(.rela*)
-	}
-
-	.rel_dyn_end :
-	{
-		*(.__rel_dyn_end)
-	}
-
-	_end = .;
-
-	. = ALIGN(8);
-
-	.bss_start : {
-		KEEP(*(.__bss_start));
-	}
-
-	.bss : {
-		*(.bss*)
-		 . = ALIGN(8);
-	}
-
-	.bss_end : {
-		KEEP(*(.__bss_end));
-	}
-
-	/DISCARD/ : { *(.dynsym) }
-	/DISCARD/ : { *(.dynstr*) }
-	/DISCARD/ : { *(.dynamic*) }
-	/DISCARD/ : { *(.plt*) }
-	/DISCARD/ : { *(.interp*) }
-	/DISCARD/ : { *(.gnu*) }
-}
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index 7b7b32c0a2..dc9d0d893c 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_SNAPDRAGON=y
-CONFIG_SYS_TEXT_BASE=0x80080000
+CONFIG_SYS_TEXT_BASE=0x8f600000
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_ENV_SIZE=0x2000
 CONFIG_ENV_OFFSET=0x0
diff --git a/doc/board/index.rst b/doc/board/index.rst
index 196b597609..a6b395238a 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -20,6 +20,7 @@ Board-specific doc
    kontron/index
    microchip/index
    openpiton/index
+   qualcomm/index
    rockchip/index
    sifive/index
    sipeed/index
diff --git a/doc/board/qualcomm/dragonboard410c.rst b/doc/board/qualcomm/dragonboard410c.rst
new file mode 100644
index 0000000000..d0de9dbcbc
--- /dev/null
+++ b/doc/board/qualcomm/dragonboard410c.rst
@@ -0,0 +1,45 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Stephan Gerhold <stephan@gerhold.net>
+
+DragonBoard 410c
+================
+
+The DragonBoard 410c is a development board based on the Qualcomm APQ8016E SoC.
+More information can be found on the `96Boards product page`_.
+
+U-Boot can be used as a replacement for Qualcomm's original Android bootloader
+(a fork of Little Kernel/LK). Like LK, it is installed directly into the ``aboot``
+partition. Note that the U-Boot port used to be loaded as an Android boot image
+through LK. This is no longer the case, now U-Boot can replace LK entirely.
+
+.. _96Boards product page: https://www.96boards.org/product/dragonboard410c/
+
+Installation
+------------
+First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``dragonboard410c``::
+
+  $ export CROSS_COMPILE=<aarch64 toolchain prefix>
+  $ make dragonboard410c_defconfig
+  $ make
+
+This will build ``u-boot.elf`` in the configured output directory.
+
+Although the DragonBoard 410c does not have secure boot set up by default,
+the firmware still expects firmware ELF images to be "signed". The signature
+does not provide any security in this case, but it provides the firmware with
+some required metadata.
+
+To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_::
+
+  $ ./qtestsign.py aboot u-boot.elf
+
+Then install the resulting ``u-boot-test-signed.mbn`` to the ``aboot`` partition
+on your device, e.g. with ``fastboot flash aboot u-boot-test-signed.mbn``.
+
+U-Boot should be running after a reboot (``fastboot reboot``).
+
+.. _qtestsign: https://github.com/msm8916-mainline/qtestsign
+
+Usage
+-----
+Press Volume Down during boot to enter Fastboot mode.
diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst
new file mode 100644
index 0000000000..f7e0aa9298
--- /dev/null
+++ b/doc/board/qualcomm/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Qualcomm
+========
+
+.. toctree::
+   :maxdepth: 2
+
+   dragonboard410c
diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
index 65537e4778..1f08508c4d 100644
--- a/include/configs/dragonboard410c.h
+++ b/include/configs/dragonboard410c.h
@@ -11,6 +11,9 @@
 #include <linux/sizes.h>
 #include <asm/arch/sysmap-apq8016.h>
 
+/* Build new ELF image from u-boot.bin (U-Boot + appended DTB) */
+#define CONFIG_REMAKE_ELF
+
 /* Physical Memory Map */
 #define PHYS_SDRAM_1			0x80000000
 /* 1008 MB (the last ~30Mb are secured for TrustZone by ATF*/
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] board: dragonboard410c: Load U-Boot directly without LK
  2021-07-07  9:06 [PATCH] board: dragonboard410c: Load U-Boot directly without LK Stephan Gerhold
@ 2021-07-10 19:07 ` Ramon Fried
  2021-07-10 19:27   ` Stephan Gerhold
  2021-07-24 20:39 ` Tom Rini
  1 sibling, 1 reply; 4+ messages in thread
From: Ramon Fried @ 2021-07-10 19:07 UTC (permalink / raw)
  To: Stephan Gerhold
  Cc: U-Boot Mailing List, Jorge Ramirez-Ortiz, Nicolas Dechesne

On Wed, Jul 7, 2021 at 12:06 PM Stephan Gerhold <stephan@gerhold.net> wrote:
>
> At the moment the U-Boot port for the DragonBoard 410c is designed
> to be loaded as an Android boot image after Qualcomm's Little Kernel (LK)
> bootloader. This is simple to set up but LK is redundant in this case,
> since everything done by LK can be also done directly by U-Boot.
>
> Dropping LK entirely has at least the following advantages:
>   - Easier installation/board code (no need for Android boot images)
>   - (Slightly) faster boot
>   - Boot directly in 64-bit without a round trip to 32-bit for LK
>
> So far this was not possible yet because of unsolved problems:
>
>   1. Signing tool: The firmware expects a "signed" ELF image with extra
>      (Qualcomm-specific) ELF headers, usually used for secure boot.
>      The DragonBoard 410c does not have secure boot by default but the
>      extra ELF headers are still required.
>
>   2. PSCI bug: There seems to be a bug in the PSCI implementation
>      (part of the TrustZone/tz firmware) that causes all other CPU cores
>      to be started in 32-bit mode if LK is missing in the boot chain.
>      This causes Linux to hang early during boot.
>
> There is a solution for both problems now:
>
>   1. qtestsign (https://github.com/msm8916-mainline/qtestsign)
>      can be used as a "signing" tool for U-Boot and other firmware.
>
>   2. A workaround for the "PSCI bug" is to execute the TZ syscall when
>      entering U-Boot. That way PSCI is made aware of the 64-bit switch
>      and starts all other CPU cores in 64-bit mode as well.
>
> Simplify the dragonboard410c board by removing all the extra code that
> is only used to build an Android boot image that can be loaded by LK.
> This allows dropping the custom linker script, special image magic,
> as well as most of the special build/installation instructions.
>
> CONFIG_REMAKE_ELF is used to build a new ELF image that has both U-Boot
> and the appended DTB combined. The resulting u-boot.elf can then be
> passed to the "signing" tool (e.g. qtestsign).
>
> The PSCI workaround is placed in the "boot0" hook that is enabled
> with CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK. The extra check for EL1 allows
> compatibility with custom firmware that enters U-Boot in EL2 or EL3,
> e.g. qhypstub (https://github.com/msm8916-mainline/qhypstub).
>
> As a first step these changes apply only to DragonBoard410c.
> Similar changes could likely also work for the DragonBoard 820c.
>
> Note that removing LK wouldn't be possible that easily without a lot of
> work already done three years ago by Ramon Fried. A lot of missing
> initialization, pinctrl etc was already added back then even though
> it was not strictly needed yet.
>
> Cc: Ramon Fried <rfried.dev@gmail.com>
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> ---
>
> Related RFC with even more detailed explanations:
> https://lore.kernel.org/u-boot/YN2F1c926HFF+JA2@gerhold.net/
>
> In my tests both U-Boot and Linux are fully functional with this patch.
> However, I would appreciate further testing, since my testing does
> likely not represent a typical usage scenario for the DragonBoard 410c.
>
> When testing, please pick the following pending patch additionally:
>   https://lore.kernel.org/u-boot/20210705121847.48432-1-stephan@gerhold.net/
> on top of u-boot/master.
>
> ---
>  arch/arm/mach-snapdragon/Kconfig              |   1 +
>  arch/arm/mach-snapdragon/include/mach/boot0.h |  54 ++++++++
>  board/qualcomm/dragonboard410c/MAINTAINERS    |   1 +
>  board/qualcomm/dragonboard410c/Makefile       |   2 -
>  .../dragonboard410c/dragonboard410c.c         |  13 --
>  board/qualcomm/dragonboard410c/head.S         |  33 -----
>  .../qualcomm/dragonboard410c/lowlevel_init.S  |  27 ----
>  board/qualcomm/dragonboard410c/readme.txt     |  73 +----------
>  board/qualcomm/dragonboard410c/u-boot.lds     | 118 ------------------
>  configs/dragonboard410c_defconfig             |   2 +-
>  doc/board/index.rst                           |   1 +
>  doc/board/qualcomm/dragonboard410c.rst        |  45 +++++++
>  doc/board/qualcomm/index.rst                  |   9 ++
>  include/configs/dragonboard410c.h             |   3 +
>  14 files changed, 120 insertions(+), 262 deletions(-)
>  create mode 100644 arch/arm/mach-snapdragon/include/mach/boot0.h
>  delete mode 100644 board/qualcomm/dragonboard410c/head.S
>  delete mode 100644 board/qualcomm/dragonboard410c/lowlevel_init.S
>  delete mode 100644 board/qualcomm/dragonboard410c/u-boot.lds
>  create mode 100644 doc/board/qualcomm/dragonboard410c.rst
>  create mode 100644 doc/board/qualcomm/index.rst
>
> diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
> index e562d693c6..0ec74fa5d3 100644
> --- a/arch/arm/mach-snapdragon/Kconfig
> +++ b/arch/arm/mach-snapdragon/Kconfig
> @@ -15,6 +15,7 @@ choice
>  config TARGET_DRAGONBOARD410C
>         bool "96Boards Dragonboard 410C"
>         select BOARD_LATE_INIT
> +       select ENABLE_ARM_SOC_BOOT0_HOOK
>         help
>           Support for 96Boards Dragonboard 410C. This board complies with
>           96Board Open Platform Specifications. Features:
> diff --git a/arch/arm/mach-snapdragon/include/mach/boot0.h b/arch/arm/mach-snapdragon/include/mach/boot0.h
> new file mode 100644
> index 0000000000..953cccad79
> --- /dev/null
> +++ b/arch/arm/mach-snapdragon/include/mach/boot0.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Workaround for "PSCI bug" on DragonBoard 410c
> + * Copyright (C) 2021 Stephan Gerhold <stephan@gerhold.net>
> + *
> + * Syscall parameters taken from Qualcomm's LK fork (scm.h):
> + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
> + *
> + * The PSCI implementation in the TrustZone/tz firmware on DragonBoard 410c has
> + * a bug that starts all other CPU cores in 32-bit mode unless the TZ syscall
> + * that switches from 32-bit to 64-bit mode is executed at least once.
> + *
> + * Normally this happens inside Qualcomm's LK bootloader which runs in 32-bit
> + * mode and uses the TZ syscall to boot a kernel in 64-bit mode. However, if
> + * U-Boot is installed to the "aboot" partition (replacing LK) the switch to
> + * 64-bit mode never happens since U-Boot is already running in 64-bit mode.
> + *
> + * A workaround for this "PSCI bug" is to execute the TZ syscall when entering
> + * U-Boot. That way PSCI is made aware of the 64-bit switch and starts all other
> + * CPU cores in 64-bit mode as well.
> + */
> +#include <linux/arm-smccc.h>
> +
> +#define ARM_SMCCC_SIP32_FAST_CALL \
> +       ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_SIP, 0)
> +
> +       /*
> +        * U-Boot might be started in EL2 or EL3 with custom firmware.
> +        * In that case, we assume that the workaround is not necessary or is
> +        * handled already by the alternative firmware. Using the syscall in EL2
> +        * would demote U-Boot to EL1; in EL3 it would probably just crash.
> +        */
> +       mrs     x0, CurrentEL
> +       cmp     x0, #(1 << 2)   /* EL1 */
> +       bne     reset
> +
> +       /* Prepare TZ syscall parameters */
> +       mov     x0, #ARM_SMCCC_SIP32_FAST_CALL
> +       movk    x0, #0x10f      /* SCM_SVC_MILESTONE_CMD_ID */
> +       mov     x1, #0x12       /* MAKE_SCM_ARGS(0x2, SMC_PARAM_TYPE_BUFFER_READ) */
> +       adr     x2, el1_system_param
> +       mov     x3, el1_system_param_end - el1_system_param
> +
> +       /* Switch PSCI to 64-bit mode. Resets CPU and returns at el1_elr */
> +       smc     #0
> +
> +       /* Something went wrong, perhaps PSCI is already in 64-bit mode? */
> +       b       reset
> +
> +       .align  3
> +el1_system_param:
> +       .quad   0, 0, 0, 0, 0, 0, 0, 0, 0       /* el1_x0-x8 */
> +       .quad   reset                           /* el1_elr */
> +el1_system_param_end:
> diff --git a/board/qualcomm/dragonboard410c/MAINTAINERS b/board/qualcomm/dragonboard410c/MAINTAINERS
> index 83448f5c13..e78f5b2d64 100644
> --- a/board/qualcomm/dragonboard410c/MAINTAINERS
> +++ b/board/qualcomm/dragonboard410c/MAINTAINERS
> @@ -4,3 +4,4 @@ S:      Maintained
>  F:     board/qualcomm/dragonboard410c/
>  F:     include/configs/dragonboard410c.h
>  F:     configs/dragonboard410c_defconfig
> +F:     doc/board/qualcomm/dragonboard410c.rst
> diff --git a/board/qualcomm/dragonboard410c/Makefile b/board/qualcomm/dragonboard410c/Makefile
> index 9b452041f4..1b99c8b0ef 100644
> --- a/board/qualcomm/dragonboard410c/Makefile
> +++ b/board/qualcomm/dragonboard410c/Makefile
> @@ -3,5 +3,3 @@
>  # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
>
>  obj-y  := dragonboard410c.o
> -obj-y  += lowlevel_init.o
> -extra-y += head.o
> diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
> index 0d282de958..3b71881cac 100644
> --- a/board/qualcomm/dragonboard410c/dragonboard410c.c
> +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
> @@ -22,19 +22,6 @@
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> -/* pointer to the device tree ammended by the firmware */
> -extern void *fw_dtb;
> -
> -void *board_fdt_blob_setup(void)
> -{
> -       if (fdt_magic(fw_dtb) != FDT_MAGIC) {
> -               printf("Firmware provided invalid dtb!\n");
> -               return NULL;
> -       }
> -
> -       return fw_dtb;
> -}
> -
>  int dram_init(void)
>  {
>         gd->ram_size = PHYS_SDRAM_1_SIZE;
> diff --git a/board/qualcomm/dragonboard410c/head.S b/board/qualcomm/dragonboard410c/head.S
> deleted file mode 100644
> index 33e9d305f9..0000000000
> --- a/board/qualcomm/dragonboard410c/head.S
> +++ /dev/null
> @@ -1,33 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0+ */
> -/*
> - * ARM64 header for proper chain-loading with Little Kernel.
> - *
> - * Little Kernel shipped with Dragonboard410C boots standard Linux images for
> - * ARM64. This file adds header that is required to boot U-Boot properly.
> - *
> - * For details see:
> - * https://www.kernel.org/doc/Documentation/arm64/booting.txt
> - *
> - * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
> - */
> -
> -#include <config.h>
> -
> -.global _arm64_header
> -_arm64_header:
> -       b _start
> -       .word 0
> -       /* Image load offset from start of RAM, little-endian */
> -       .quad   CONFIG_SYS_TEXT_BASE-PHYS_SDRAM_1
> -       /* Effective size of kernel image, little-endian */
> -       .quad   0 /* 0x60000 - ignored */
> -       /* Informative flags, little-endian */
> -       .quad   0
> -       .quad   0                               /* reserved */
> -       .quad   0                               /* reserved */
> -       .quad   0                               /* reserved */
> -       .byte   0x41                            /* Magic number, "ARM\x64" */
> -       .byte   0x52
> -       .byte   0x4d
> -       .byte   0x64
> -       .word   0                               /* reserved */
> diff --git a/board/qualcomm/dragonboard410c/lowlevel_init.S b/board/qualcomm/dragonboard410c/lowlevel_init.S
> deleted file mode 100644
> index 762fed5617..0000000000
> --- a/board/qualcomm/dragonboard410c/lowlevel_init.S
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0+ */
> -/*
> - * (C) Copyright 2016
> - * Cédric Schieli <cschieli@gmail.com>
> - */
> -
> -#include <config.h>
> -
> -.align 8
> -.global fw_dtb
> -fw_dtb:
> -       .dword 0x0
> -
> -/*
> - * Routine: save_boot_params (called after reset from start.S)
> - * Description: save ATAG/FDT address provided by the firmware at boot time
> - */
> -
> -.global save_boot_params
> -save_boot_params:
> -
> -       /* The firmware provided ATAG/FDT address can be found in r2/x0 */
> -       adr     x8, fw_dtb
> -       str     x0, [x8]
> -
> -       /* Returns */
> -       b       save_boot_params_ret
> diff --git a/board/qualcomm/dragonboard410c/readme.txt b/board/qualcomm/dragonboard410c/readme.txt
> index a90d0f52e7..dfdb299fb7 100644
> --- a/board/qualcomm/dragonboard410c/readme.txt
> +++ b/board/qualcomm/dragonboard410c/readme.txt
> @@ -1,69 +1,6 @@
> -# SPDX-License-Identifier: GPL-2.0+
> -#
> -# (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
> +Documentation for DragonBoard 410c is now located at:
> +    doc/board/qualcomm/dragonboard410c.rst
>
> -Build & Run instructions:
> -
> -1) Install mkbootimg and dtbTool from
> -   git://codeaurora.org/quic/kernel/skales (15ece94f09 worked for me)
> -2) Setup CROSS_COMPILE to aarch64 compiler
> -3) make dragonboard410c_config
> -4) make
> -5) generate fake, empty ramdisk (can have 0 bytes)
> -$ touch rd
> -
> -6) Generate qualcomm device tree table with dtbTool [1]
> -$ dtbTool -o dt.img arch/arm/dts
> -
> -7) Generate Android boot image with mkbootimg [2]:
> -$ mkbootimg --kernel=u-boot-dtb.bin --output=u-boot.img --dt=dt.img  \
> -  --pagesize 2048 --base 0x80000000 --ramdisk=rd --cmdline=""
> -
> -8) Enter fastboot (reboot board with vol- button pressed)
> -
> -9) Boot it:
> -$ fastboot boot u-boot.img
> -or flash as kernel:
> -$ fastboot flash boot u-boot.img
> -$ fastboot reboot
> -
> -
> -What is working:
> -- UART
> -- GPIO (SoC)
> -- SD
> -- eMMC
> -- Reset
> -- USB in EHCI mode (usb starts does switch device->host, usb stop does the opposite)
> -- PMIC GPIOS (but not in generic subsystem)
> -- PMIC "special" buttons (power, vol-)
> -
> -What is not working / known bugs:
> -- SDHCI is slow (~2.5MiB/s for SD and eMMC)
> -
> -[1] To boot any kernel image, Little Kernel requires valid device tree for the
> -platform it runs on. dtbTool creates device tree table that Little Kernel scans.
> -Later on proper device tree is passed to next boot stage.
> -Full device tree is not required to boot u-boot. Enough would be:
> -/dts-v1/;
> -
> -/ {
> -       model = "Qualcomm Technologies, Inc. Dragonboard 410c";
> -       compatible = "qcom,dragonboard", "qcom,apq8016-sbc";
> -       qcom,msm-id = <0xce 0x0 0xf8 0x0 0xf9 0x0 0xfa 0x0 0xf7 0x0>;
> -       qcom,board-id = <0x10018 0x0>;
> -       #address-cells = <0x2>;
> -       #size-cells = <0x2>;
> -       chosen { };
> -       aliases { };
> -
> -       memory {
> -               device_type = "memory";
> -               reg = <0 0x80000000 0 0x3da00000>;
> -       };
> -};
> -
> -but for simplicity (and because size of image is not that critical) we use
> -existing Qualcomm device trees.
> -
> -[2] Note that ramdisk is required, even if it is unused.
> +Note that the installation method has changed: U-Boot is now installed into the
> +"aboot" partition (replacing Little Kernel/LK). It is no longer packaged into
> +an Android boot image and loaded through Qualcomm's LK bootloader.
> diff --git a/board/qualcomm/dragonboard410c/u-boot.lds b/board/qualcomm/dragonboard410c/u-boot.lds
> deleted file mode 100644
> index fc1bba8cf0..0000000000
> --- a/board/qualcomm/dragonboard410c/u-boot.lds
> +++ /dev/null
> @@ -1,118 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0+ */
> -/*
> - * Override linker script for fastboot-readable images
> - *
> - * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
> - *
> - * Based on arch/arm/cpu/armv8/u-boot.lds (Just add header)
> - */
> -
> -OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
> -OUTPUT_ARCH(aarch64)
> -ENTRY(_arm64_header)
> -SECTIONS
> -{
> -       . = 0x00000000;
> -
> -       . = ALIGN(8);
> -       .text :
> -       {
> -               *(.__image_copy_start)
> -               board/qualcomm/dragonboard410c/head.o (.text*)
> -               CPUDIR/start.o (.text*)
> -       }
> -
> -       /* This needs to come before *(.text*) */
> -       .efi_runtime : {
> -                __efi_runtime_start = .;
> -               *(.text.efi_runtime*)
> -               *(.rodata.efi_runtime*)
> -               *(.data.efi_runtime*)
> -                __efi_runtime_stop = .;
> -       }
> -
> -       .text_rest :
> -       {
> -               *(.text*)
> -       }
> -
> -       . = ALIGN(8);
> -       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
> -
> -       . = ALIGN(8);
> -       .data : {
> -               *(.data*)
> -       }
> -
> -       . = ALIGN(8);
> -
> -       . = .;
> -
> -       . = ALIGN(8);
> -       .u_boot_list : {
> -               KEEP(*(SORT(.u_boot_list*)));
> -       }
> -
> -       . = ALIGN(8);
> -
> -       .efi_runtime : {
> -                __efi_runtime_start = .;
> -               *(efi_runtime_text)
> -               *(efi_runtime_data)
> -                __efi_runtime_stop = .;
> -       }
> -
> -       .efi_runtime_rel : {
> -                __efi_runtime_rel_start = .;
> -               *(.rel*.efi_runtime)
> -               *(.rel*.efi_runtime.*)
> -                __efi_runtime_rel_stop = .;
> -       }
> -
> -       . = ALIGN(8);
> -
> -       .image_copy_end :
> -       {
> -               *(.__image_copy_end)
> -       }
> -
> -       . = ALIGN(8);
> -
> -       .rel_dyn_start :
> -       {
> -               *(.__rel_dyn_start)
> -       }
> -
> -       .rela.dyn : {
> -               *(.rela*)
> -       }
> -
> -       .rel_dyn_end :
> -       {
> -               *(.__rel_dyn_end)
> -       }
> -
> -       _end = .;
> -
> -       . = ALIGN(8);
> -
> -       .bss_start : {
> -               KEEP(*(.__bss_start));
> -       }
> -
> -       .bss : {
> -               *(.bss*)
> -                . = ALIGN(8);
> -       }
> -
> -       .bss_end : {
> -               KEEP(*(.__bss_end));
> -       }
> -
> -       /DISCARD/ : { *(.dynsym) }
> -       /DISCARD/ : { *(.dynstr*) }
> -       /DISCARD/ : { *(.dynamic*) }
> -       /DISCARD/ : { *(.plt*) }
> -       /DISCARD/ : { *(.interp*) }
> -       /DISCARD/ : { *(.gnu*) }
> -}
> diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
> index 7b7b32c0a2..dc9d0d893c 100644
> --- a/configs/dragonboard410c_defconfig
> +++ b/configs/dragonboard410c_defconfig
> @@ -1,6 +1,6 @@
>  CONFIG_ARM=y
>  CONFIG_ARCH_SNAPDRAGON=y
> -CONFIG_SYS_TEXT_BASE=0x80080000
> +CONFIG_SYS_TEXT_BASE=0x8f600000
>  CONFIG_NR_DRAM_BANKS=1
>  CONFIG_ENV_SIZE=0x2000
>  CONFIG_ENV_OFFSET=0x0
> diff --git a/doc/board/index.rst b/doc/board/index.rst
> index 196b597609..a6b395238a 100644
> --- a/doc/board/index.rst
> +++ b/doc/board/index.rst
> @@ -20,6 +20,7 @@ Board-specific doc
>     kontron/index
>     microchip/index
>     openpiton/index
> +   qualcomm/index
>     rockchip/index
>     sifive/index
>     sipeed/index
> diff --git a/doc/board/qualcomm/dragonboard410c.rst b/doc/board/qualcomm/dragonboard410c.rst
> new file mode 100644
> index 0000000000..d0de9dbcbc
> --- /dev/null
> +++ b/doc/board/qualcomm/dragonboard410c.rst
> @@ -0,0 +1,45 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +.. sectionauthor:: Stephan Gerhold <stephan@gerhold.net>
> +
> +DragonBoard 410c
> +================
> +
> +The DragonBoard 410c is a development board based on the Qualcomm APQ8016E SoC.
> +More information can be found on the `96Boards product page`_.
> +
> +U-Boot can be used as a replacement for Qualcomm's original Android bootloader
> +(a fork of Little Kernel/LK). Like LK, it is installed directly into the ``aboot``
> +partition. Note that the U-Boot port used to be loaded as an Android boot image
> +through LK. This is no longer the case, now U-Boot can replace LK entirely.
> +
> +.. _96Boards product page: https://www.96boards.org/product/dragonboard410c/
> +
> +Installation
> +------------
> +First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``dragonboard410c``::
> +
> +  $ export CROSS_COMPILE=<aarch64 toolchain prefix>
> +  $ make dragonboard410c_defconfig
> +  $ make
> +
> +This will build ``u-boot.elf`` in the configured output directory.
> +
> +Although the DragonBoard 410c does not have secure boot set up by default,
> +the firmware still expects firmware ELF images to be "signed". The signature
> +does not provide any security in this case, but it provides the firmware with
> +some required metadata.
> +
> +To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_::
> +
> +  $ ./qtestsign.py aboot u-boot.elf
> +
> +Then install the resulting ``u-boot-test-signed.mbn`` to the ``aboot`` partition
> +on your device, e.g. with ``fastboot flash aboot u-boot-test-signed.mbn``.
> +
> +U-Boot should be running after a reboot (``fastboot reboot``).
> +
> +.. _qtestsign: https://github.com/msm8916-mainline/qtestsign
> +
> +Usage
> +-----
> +Press Volume Down during boot to enter Fastboot mode.
> diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst
> new file mode 100644
> index 0000000000..f7e0aa9298
> --- /dev/null
> +++ b/doc/board/qualcomm/index.rst
> @@ -0,0 +1,9 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +
> +Qualcomm
> +========
> +
> +.. toctree::
> +   :maxdepth: 2
> +
> +   dragonboard410c
> diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
> index 65537e4778..1f08508c4d 100644
> --- a/include/configs/dragonboard410c.h
> +++ b/include/configs/dragonboard410c.h
> @@ -11,6 +11,9 @@
>  #include <linux/sizes.h>
>  #include <asm/arch/sysmap-apq8016.h>
>
> +/* Build new ELF image from u-boot.bin (U-Boot + appended DTB) */
> +#define CONFIG_REMAKE_ELF
> +
>  /* Physical Memory Map */
>  #define PHYS_SDRAM_1                   0x80000000
>  /* 1008 MB (the last ~30Mb are secured for TrustZone by ATF*/
> --
> 2.32.0
>
Thanks Stephan, it looks very good.
I started testing it, it builds correctly and I flashed and everything
seems to work.
I do have a problem with my TFTP setup, so I didn't boot Linux yet,
but I will get to it, if it will boot successfully we can merge this
one.

U-boot doesn't know how to boot qcom android kernel partitions, I'm
not sure this is something I even want to start supporting in U-boot.
Nico, do you think you can change the format of the BOOT partition to
host a u-boot FIT image ?

Thanks,
Ramon

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] board: dragonboard410c: Load U-Boot directly without LK
  2021-07-10 19:07 ` Ramon Fried
@ 2021-07-10 19:27   ` Stephan Gerhold
  0 siblings, 0 replies; 4+ messages in thread
From: Stephan Gerhold @ 2021-07-10 19:27 UTC (permalink / raw)
  To: Ramon Fried; +Cc: U-Boot Mailing List, Jorge Ramirez-Ortiz, Nicolas Dechesne

On Sat, Jul 10, 2021 at 10:07:28PM +0300, Ramon Fried wrote:
> On Wed, Jul 7, 2021 at 12:06 PM Stephan Gerhold <stephan@gerhold.net> wrote:
> >
> > At the moment the U-Boot port for the DragonBoard 410c is designed
> > to be loaded as an Android boot image after Qualcomm's Little Kernel (LK)
> > bootloader. This is simple to set up but LK is redundant in this case,
> > since everything done by LK can be also done directly by U-Boot.
> >
> > Dropping LK entirely has at least the following advantages:
> >   - Easier installation/board code (no need for Android boot images)
> >   - (Slightly) faster boot
> >   - Boot directly in 64-bit without a round trip to 32-bit for LK
> >
> > So far this was not possible yet because of unsolved problems:
> >
> >   1. Signing tool: The firmware expects a "signed" ELF image with extra
> >      (Qualcomm-specific) ELF headers, usually used for secure boot.
> >      The DragonBoard 410c does not have secure boot by default but the
> >      extra ELF headers are still required.
> >
> >   2. PSCI bug: There seems to be a bug in the PSCI implementation
> >      (part of the TrustZone/tz firmware) that causes all other CPU cores
> >      to be started in 32-bit mode if LK is missing in the boot chain.
> >      This causes Linux to hang early during boot.
> >
> > There is a solution for both problems now:
> >
> >   1. qtestsign (https://github.com/msm8916-mainline/qtestsign)
> >      can be used as a "signing" tool for U-Boot and other firmware.
> >
> >   2. A workaround for the "PSCI bug" is to execute the TZ syscall when
> >      entering U-Boot. That way PSCI is made aware of the 64-bit switch
> >      and starts all other CPU cores in 64-bit mode as well.
> >
> > Simplify the dragonboard410c board by removing all the extra code that
> > is only used to build an Android boot image that can be loaded by LK.
> > This allows dropping the custom linker script, special image magic,
> > as well as most of the special build/installation instructions.
> >
> > CONFIG_REMAKE_ELF is used to build a new ELF image that has both U-Boot
> > and the appended DTB combined. The resulting u-boot.elf can then be
> > passed to the "signing" tool (e.g. qtestsign).
> >
> > The PSCI workaround is placed in the "boot0" hook that is enabled
> > with CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK. The extra check for EL1 allows
> > compatibility with custom firmware that enters U-Boot in EL2 or EL3,
> > e.g. qhypstub (https://github.com/msm8916-mainline/qhypstub).
> >
> > As a first step these changes apply only to DragonBoard410c.
> > Similar changes could likely also work for the DragonBoard 820c.
> >
> > Note that removing LK wouldn't be possible that easily without a lot of
> > work already done three years ago by Ramon Fried. A lot of missing
> > initialization, pinctrl etc was already added back then even though
> > it was not strictly needed yet.
> >
> > Cc: Ramon Fried <rfried.dev@gmail.com>
> > Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> > ---
> >
> > Related RFC with even more detailed explanations:
> > https://lore.kernel.org/u-boot/YN2F1c926HFF+JA2@gerhold.net/
> >
> > In my tests both U-Boot and Linux are fully functional with this patch.
> > However, I would appreciate further testing, since my testing does
> > likely not represent a typical usage scenario for the DragonBoard 410c.
> >
> > When testing, please pick the following pending patch additionally:
> >   https://lore.kernel.org/u-boot/20210705121847.48432-1-stephan@gerhold.net/
> > on top of u-boot/master.
> >
> > ---
> > [...]
>
> Thanks Stephan, it looks very good.
> I started testing it, it builds correctly and I flashed and everything
> seems to work.
> I do have a problem with my TFTP setup, so I didn't boot Linux yet,
> but I will get to it, if it will boot successfully we can merge this
> one.
> 
> U-boot doesn't know how to boot qcom android kernel partitions, I'm
> not sure this is something I even want to start supporting in U-boot.

It's probably not too hard to support this (I actually boot the same
Android boot images on both LK and U-Boot via "fastboot boot", because
this is the workflow I'm used to). But I agree that anything else
(i.e. reading the images from partitions) is not worth the effort.

> Nico, do you think you can change the format of the BOOT partition to
> host a u-boot FIT image ?
> 

Is a "boot" partition with a binary image even useful at all?
I would expect that all typical Linux distributions except Android have
a separate boot partition with a file system, so setting something up
that works with the generic distro configuration (doc/README.distro)
would be probably best. This would also avoid having to re-build the
image just to change the cmdline for example.

Stephan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] board: dragonboard410c: Load U-Boot directly without LK
  2021-07-07  9:06 [PATCH] board: dragonboard410c: Load U-Boot directly without LK Stephan Gerhold
  2021-07-10 19:07 ` Ramon Fried
@ 2021-07-24 20:39 ` Tom Rini
  1 sibling, 0 replies; 4+ messages in thread
From: Tom Rini @ 2021-07-24 20:39 UTC (permalink / raw)
  To: Stephan Gerhold
  Cc: u-boot, Ramon Fried, Jorge Ramirez-Ortiz, Nicolas Dechesne

[-- Attachment #1: Type: text/plain, Size: 2930 bytes --]

On Wed, Jul 07, 2021 at 11:06:02AM +0200, Stephan Gerhold wrote:

> At the moment the U-Boot port for the DragonBoard 410c is designed
> to be loaded as an Android boot image after Qualcomm's Little Kernel (LK)
> bootloader. This is simple to set up but LK is redundant in this case,
> since everything done by LK can be also done directly by U-Boot.
> 
> Dropping LK entirely has at least the following advantages:
>   - Easier installation/board code (no need for Android boot images)
>   - (Slightly) faster boot
>   - Boot directly in 64-bit without a round trip to 32-bit for LK
> 
> So far this was not possible yet because of unsolved problems:
> 
>   1. Signing tool: The firmware expects a "signed" ELF image with extra
>      (Qualcomm-specific) ELF headers, usually used for secure boot.
>      The DragonBoard 410c does not have secure boot by default but the
>      extra ELF headers are still required.
> 
>   2. PSCI bug: There seems to be a bug in the PSCI implementation
>      (part of the TrustZone/tz firmware) that causes all other CPU cores
>      to be started in 32-bit mode if LK is missing in the boot chain.
>      This causes Linux to hang early during boot.
> 
> There is a solution for both problems now:
> 
>   1. qtestsign (https://github.com/msm8916-mainline/qtestsign)
>      can be used as a "signing" tool for U-Boot and other firmware.
> 
>   2. A workaround for the "PSCI bug" is to execute the TZ syscall when
>      entering U-Boot. That way PSCI is made aware of the 64-bit switch
>      and starts all other CPU cores in 64-bit mode as well.
> 
> Simplify the dragonboard410c board by removing all the extra code that
> is only used to build an Android boot image that can be loaded by LK.
> This allows dropping the custom linker script, special image magic,
> as well as most of the special build/installation instructions.
> 
> CONFIG_REMAKE_ELF is used to build a new ELF image that has both U-Boot
> and the appended DTB combined. The resulting u-boot.elf can then be
> passed to the "signing" tool (e.g. qtestsign).
> 
> The PSCI workaround is placed in the "boot0" hook that is enabled
> with CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK. The extra check for EL1 allows
> compatibility with custom firmware that enters U-Boot in EL2 or EL3,
> e.g. qhypstub (https://github.com/msm8916-mainline/qhypstub).
> 
> As a first step these changes apply only to DragonBoard410c.
> Similar changes could likely also work for the DragonBoard 820c.
> 
> Note that removing LK wouldn't be possible that easily without a lot of
> work already done three years ago by Ramon Fried. A lot of missing
> initialization, pinctrl etc was already added back then even though
> it was not strictly needed yet.
> 
> Cc: Ramon Fried <rfried.dev@gmail.com>
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>

Applied to u-boot/master, thanks!

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-24 20:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-07  9:06 [PATCH] board: dragonboard410c: Load U-Boot directly without LK Stephan Gerhold
2021-07-10 19:07 ` Ramon Fried
2021-07-10 19:27   ` Stephan Gerhold
2021-07-24 20:39 ` Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.