1Qualcomm Snapdragon 410 (MSM8916/APQ8016) 2========================================= 3 4The `Qualcomm Snapdragon 410`_ is Qualcomm's first 64-bit SoC, released in 2014 5with four ARM Cortex-A53 cores. There are differents variants (MSM8916, 6APQ8016(E), ...) that are all very similar. A popular device based on APQ8016E 7is the `DragonBoard 410c`_ single-board computer, but the SoC is also used in 8various mid-range smartphones/tablets. 9 10The TF-A port for MSM8916 provides a minimal, community-maintained 11EL3 firmware. It is primarily based on information from the public 12`Snapdragon 410E Technical Reference Manual`_ combined with a lot of 13trial and error to actually make it work. 14 15.. note:: 16 Unlike the :doc:`QTI SC7180/SC7280 <qti>` ports, this port does **not** 17 make use of a proprietary binary components (QTISECLIB). It is fully 18 open-source but therefore limited to publicly documented hardware 19 components. 20 21Functionality 22------------- 23The TF-A port is much more minimal compared to the original firmware and 24therefore expects the non-secure world (e.g. Linux) to manage more hardware, 25such as the SMMUs and all remote processors (RPM, WCNSS, Venus, Modem). 26Everything except modem is currently functional with a slightly modified version 27of mainline Linux. 28 29.. warning:: 30 This port is **not secure**. There is no special secure memory and the 31 used DRAM is available from both the non-secure and secure worlds. 32 Unfortunately, the hardware used for memory protection is not described 33 in the APQ8016E documentation. 34 35The port is primarily intended as a minimal PSCI implementation (without a 36separate secure world) where this limitation is not a big problem. Booting 37secondary CPU cores (PSCI ``CPU_ON``) is supported. Basic CPU core power 38management (``CPU_SUSPEND``) is functional but still work-in-progress and 39will be added later once ready. 40 41Boot Flow 42--------- 43BL31 (AArch64) or BL32/SP_MIN (AArch32) replaces the original ``tz`` firmware 44in the boot flow:: 45 46 Boot ROM (PBL) -> SBL -> BL31 (EL3) -> U-Boot (EL2) -> Linux (EL2) 47 48After initialization the normal world starts at a fixed entry address in EL2/HYP 49mode, configured using ``PRELOADED_BL33_BASE``. At runtime, it is expected that 50the normal world bootloader was already loaded into RAM by a previous firmware 51component (usually SBL) and that it is capable of running in EL2/HYP mode. 52 53`U-Boot for DragonBoard 410c`_ is recommended if possible. The original Little 54Kernel-based bootloader from Qualcomm does not support EL2/HYP, but can be 55booted using an additional shim loader such as `tfalkstub`_. 56 57Build 58----- 59It is possible to build for either AArch64 or AArch32. AArch64 is the preferred 60build option. 61 62AArch64 (BL31) 63^^^^^^^^^^^^^^ 64Setup the cross compiler for AArch64 and build BL31 for ``msm8916``:: 65 66 $ make CROSS_COMPILE=aarch64-none-elf- PLAT=msm8916 67 68The BL31 ELF image is generated in ``build/msm8916/release/bl31/bl31.elf``. 69 70AArch32 (BL32/SP_MIN) 71^^^^^^^^^^^^^^^^^^^^^ 72Setup the cross compiler for AArch32 and build BL32 with SP_MIN for ``msm8916``:: 73 74 $ make CROSS_COMPILE=arm-none-eabi- PLAT=msm8916 ARCH=aarch32 AARCH32_SP=sp_min 75 76The BL32 ELF image is generated in ``build/msm8916/release/bl32/bl32.elf``. 77 78Build Options 79------------- 80Some options can be changed at build time by adding them to the make command line: 81 82 * ``QTI_UART_NUM``: Number of UART controller to use for debug output and crash 83 reports. This must be the same UART as used by earlier boot firmware since 84 the UART controller does not get fully initialized at the moment. Defaults to 85 the usual debug UART used for the platform (see ``platform.mk``). 86 * ``QTI_RUNTIME_UART``: By default (``0``) the UART is only used for the boot 87 process and critical crashes. If set to ``1`` it is also used for runtime 88 messages. Note that this option can only be used if the UART is reserved in 89 the normal world and the necessary clocks remain enabled. 90 91The memory region used for the different firmware components is not fixed and 92can be changed on the make command line. The default values match the addresses 93used by the original firmware (see ``platform.mk``): 94 95 * ``PRELOADED_BL33_BASE``: The entry address for the normal world. Usually 96 refers to the first bootloader (e.g. U-Boot). 97 * ``BL31_BASE``: Base address for the BL31 firmware component. Must point to 98 a 64K-aligned memory region with at least 128 KiB space that is permanently 99 reserved in the normal world. 100 * ``BL32_BASE``: Base address for the BL32 firmware component. 101 102 * **AArch32:** BL32 is used in place of BL31, so the option is equivalent to 103 ``BL31_BASE``. 104 * **AArch64:** Secure-EL1 Payload. Defaults to using 128 KiB of space 105 directly after BL31. For testing only, the port is primarily intended as 106 a minimal PSCI implementation without a separate secure world. 107 108Installation 109------------ 110The ELF image must be "signed" before flashing it, even if the board has secure 111boot disabled. In this case the signature does not provide any security, 112but it provides the firmware with required metadata. 113 114The `DragonBoard 410c`_ does not have secure boot enabled by default. In this 115case you can simply sign the ELF image using a randomly generated key. You can 116use e.g. `qtestsign`_:: 117 118 $ ./qtestsign.py tz build/msm8916/release/bl31/bl31.elf 119 120Then install the resulting ``build/msm8916/release/bl31/bl31-test-signed.mbn`` 121to the ``tz`` partition on the device. BL31 should be running after a reboot. 122 123.. note:: 124 On AArch32 the ELF image is called ``bl32.elf``. 125 The installation procedure is identical. 126 127.. warning:: 128 Do not flash incorrectly signed firmware on devices that have secure 129 boot enabled! Make sure that you have a way to recover the board in case 130 of problems (e.g. using EDL). 131 132Boot Trace 133---------- 134 135AArch64 (BL31) 136^^^^^^^^^^^^^^ 137BL31 prints some lines on the debug console, which will usually look like this 138(with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown):: 139 140 ... 141 S - DDR Frequency, 400 MHz 142 NOTICE: BL31: v2.6(debug):v2.6 143 NOTICE: BL31: Built : 20:00:00, Dec 01 2021 144 INFO: BL31: Platform setup start 145 INFO: ARM GICv2 driver initialized 146 INFO: BL31: Platform setup done 147 INFO: BL31: Initializing runtime services 148 INFO: BL31: cortex_a53: CPU workaround for 819472 was applied 149 INFO: BL31: cortex_a53: CPU workaround for 824069 was applied 150 INFO: BL31: cortex_a53: CPU workaround for 826319 was applied 151 INFO: BL31: cortex_a53: CPU workaround for 827319 was applied 152 INFO: BL31: cortex_a53: CPU workaround for 835769 was applied 153 INFO: BL31: cortex_a53: CPU workaround for disable_non_temporal_hint was applied 154 INFO: BL31: cortex_a53: CPU workaround for 843419 was applied 155 INFO: BL31: cortex_a53: CPU workaround for 1530924 was applied 156 INFO: BL31: Preparing for EL3 exit to normal world 157 INFO: Entry point address = 0x8f600000 158 INFO: SPSR = 0x3c9 159 160 U-Boot 2021.10 (Dec 01 2021 - 20:00:00 +0000) 161 Qualcomm-DragonBoard 410C 162 ... 163 164AArch32 (BL32/SP_MIN) 165^^^^^^^^^^^^^^^^^^^^^ 166BL32/SP_MIN prints some lines on the debug console, which will usually look like 167this (with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown):: 168 169 ... 170 S - DDR Frequency, 400 MHz 171 NOTICE: SP_MIN: v2.8(debug):v2.8 172 NOTICE: SP_MIN: Built : 23:03:31, Mar 31 2023 173 INFO: SP_MIN: Platform setup start 174 INFO: ARM GICv2 driver initialized 175 INFO: SP_MIN: Platform setup done 176 INFO: SP_MIN: Initializing runtime services 177 INFO: BL32: cortex_a53: CPU workaround for 819472 was applied 178 INFO: BL32: cortex_a53: CPU workaround for 824069 was applied 179 INFO: BL32: cortex_a53: CPU workaround for 826319 was applied 180 INFO: BL32: cortex_a53: CPU workaround for 827319 was applied 181 INFO: BL32: cortex_a53: CPU workaround for disable_non_temporal_hint was applied 182 INFO: SP_MIN: Preparing exit to normal world 183 INFO: Entry point address = 0x86400000 184 INFO: SPSR = 0x1da 185 Android Bootloader - UART_DM Initialized!!! 186 [0] welcome to lk 187 ... 188 189.. _Qualcomm Snapdragon 410: https://www.qualcomm.com/products/snapdragon-processors-410 190.. _DragonBoard 410c: https://www.96boards.org/product/dragonboard410c/ 191.. _Snapdragon 410E Technical Reference Manual: https://developer.qualcomm.com/download/sd410/snapdragon-410e-technical-reference-manual.pdf 192.. _U-Boot for DragonBoard 410c: https://u-boot.readthedocs.io/en/latest/board/qualcomm/dragonboard410c.html 193.. _qtestsign: https://github.com/msm8916-mainline/qtestsign 194.. _tfalkstub: https://github.com/msm8916-mainline/tfalkstub 195