diff options
-rw-r--r-- | arch/arm/mach-snapdragon/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-snapdragon/include/mach/boot0.h | 54 | ||||
-rw-r--r-- | board/qualcomm/dragonboard410c/MAINTAINERS | 1 | ||||
-rw-r--r-- | board/qualcomm/dragonboard410c/Makefile | 2 | ||||
-rw-r--r-- | board/qualcomm/dragonboard410c/dragonboard410c.c | 13 | ||||
-rw-r--r-- | board/qualcomm/dragonboard410c/head.S | 33 | ||||
-rw-r--r-- | board/qualcomm/dragonboard410c/lowlevel_init.S | 27 | ||||
-rw-r--r-- | board/qualcomm/dragonboard410c/readme.txt | 73 | ||||
-rw-r--r-- | board/qualcomm/dragonboard410c/u-boot.lds | 118 | ||||
-rw-r--r-- | configs/dragonboard410c_defconfig | 2 | ||||
-rw-r--r-- | doc/board/index.rst | 1 | ||||
-rw-r--r-- | doc/board/qualcomm/dragonboard410c.rst | 45 | ||||
-rw-r--r-- | doc/board/qualcomm/index.rst | 9 | ||||
-rw-r--r-- | include/configs/dragonboard410c.h | 3 |
14 files changed, 120 insertions, 262 deletions
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig index e562d69..0ec74fa 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 0000000..953ccca --- /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 83448f5..e78f5b2 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 9b45204..1b99c8b 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 0d282de..3b71881 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 33e9d30..0000000 --- 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 762fed5..0000000 --- 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 a90d0f5..dfdb299 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 fc1bba8..0000000 --- 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 7b7b32c..dc9d0d8 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 196b597..a6b3952 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 0000000..d0de9db --- /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 0000000..f7e0aa9 --- /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 65537e4..1f08508 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*/ |