7.34.Qualcomm MSM8916
The MSM8916 platform port in TF-A supports multiple similar Qualcomm SoCs:
System-on-Chip (SoC) | TF-A Platform | Application CPU | Supports |
---|---|---|---|
Snapdragon 410(MSM8x16, APQ8016(E))(DragonBoard 410c) |
| 4x ARM Cortex-A53 | AArch64/AArch32 |
Snapdragon 615(MSM8x39, APQ8039) |
| 4x ARM Cortex-A534x ARM Cortex-A53 | AArch64/AArch32 |
Snapdragon 210(MSM8x09, APQ8009) |
| 4x ARM Cortex-A7 | AArch32 only |
Snapdragon X5 Modem(MDM9x07) |
| 1x ARM Cortex-A7 | AArch32 only |
It provides a minimal, community-maintained EL3 firmware and PSCI implementation,based on information from the publicSnapdragon 410E Technical Reference Manualcombined with a lot of trial and error to actually make it work.
Note
Unlike theQTI SC7180/SC7280 ports, this port doesnotmake use of a proprietary binary components (QTISECLIB). It is fullyopen-source but therefore limited to publicly documented hardwarecomponents.
7.34.1.Functionality
The TF-A port is much more minimal compared to the original firmware andtherefore expects the non-secure world (e.g. Linux) to manage more hardware,such as the SMMUs and all remote processors (RPM, WCNSS, Venus, Modem).Everything except modem is currently functional with a slightly modified versionof mainline Linux.
Warning
This port isnot secure. There is no special secure memory and theused DRAM is available from both the non-secure and secure worlds.Unfortunately, the hardware used for memory protection is not describedin the APQ8016E documentation.
The port is primarily intended as a minimal PSCI implementation (without aseparate secure world) where this limitation is not a big problem. Bootingsecondary CPU cores (PSCICPU_ON
) is supported. Basic CPU core powermanagement (CPU_SUSPEND
) is functional but still work-in-progress andwill be added later once ready.
7.34.2.Boot Flow
BL31 (AArch64) or BL32/SP_MIN (AArch32) replaces the originaltz
firmwarein the boot flow:
BootROM(PBL)->SBL->BL31(EL3)->U-Boot(EL2)->Linux(EL2)
After initialization the normal world starts at a fixed entry address in EL2/HYPmode, configured usingPRELOADED_BL33_BASE
. At runtime, it is expected thatthe normal world bootloader was already loaded into RAM by a previous firmwarecomponent (usually SBL) and that it is capable of running in EL2/HYP mode.
U-Boot for DragonBoard 410c is recommended if possible. The original LittleKernel-based bootloader from Qualcomm does not support EL2/HYP, but can bebooted using an additional shim loader such astfalkstub.
7.34.3.Build
It is possible to build for either AArch64 or AArch32. Some platforms use 32-bitCPUs that only support AArch32 (see table above). For all others AArch64 is thepreferred build option.
7.34.3.1.AArch64 (BL31)
Setup the cross compiler for AArch64 and build BL31 for one of the platforms inthe table above:
$ make CROSS_COMPILE=aarch64-none-elf- PLAT=...
The BL31 ELF image is generated inbuild/$PLAT/release/bl31/bl31.elf
.
7.34.3.2.AArch32 (BL32/SP_MIN)
Setup the cross compiler for AArch32 and build BL32 with SP_MIN for one of theplatforms in the table above:
$ make CROSS_COMPILE=arm-none-eabi- PLAT=... ARCH=aarch32 AARCH32_SP=sp_min
The BL32 ELF image is generated inbuild/$PLAT/release/bl32/bl32.elf
.
7.34.4.Build Options
Some options can be changed at build time by adding them to the make command line:
QTI_UART_NUM
: Number of UART controller to use for debug output and crashreports. This must be the same UART as used by earlier boot firmware sincethe UART controller does not get fully initialized at the moment. Defaults tothe usual debug UART used for the platform (seeplatform.mk
).
QTI_RUNTIME_UART
: By default (0
) the UART is only used for the bootprocess and critical crashes. If set to1
it is also used for runtimemessages. Note that this option can only be used if the UART is reserved inthe normal world and the necessary clocks remain enabled.
The memory region used for the different firmware components is not fixed andcan be changed on the make command line. The default values match the addressesused by the original firmware (seeplatform.mk
):
PRELOADED_BL33_BASE
: The entry address for the normal world. Usuallyrefers to the first bootloader (e.g. U-Boot).
BL31_BASE
: Base address for the BL31 firmware component. Must point toa 64K-aligned memory region with at least 128 KiB space that is permanentlyreserved in the normal world.
BL32_BASE
: Base address for the BL32 firmware component.
AArch32: BL32 is used in place of BL31, so the option is equivalent to
BL31_BASE
.AArch64: Secure-EL1 Payload. Defaults to using 128 KiB of spacedirectly after BL31. For testing only, the port is primarily intended asa minimal PSCI implementation without a separate secure world.
7.34.5.Installation
The ELF image must be “signed” before flashing it, even if the board has secureboot disabled. In this case the signature does not provide any security,but it provides the firmware with required metadata.
TheDragonBoard 410c does not have secure boot enabled by default. In thiscase you can simply sign the ELF image using a randomly generated key. You canuse e.g.qtestsign:
$ ./qtestsign.py tz build/msm8916/release/bl31/bl31.elf
Then install the resultingbuild/msm8916/release/bl31/bl31-test-signed.mbn
to thetz
partition on the device. BL31 should be running after a reboot.
Note
On AArch32 the ELF image is calledbl32.elf
.The installation procedure is identical.
Warning
Do not flash incorrectly signed firmware on devices that have secureboot enabled! Make sure that you have a way to recover the board in caseof problems (e.g. using EDL).
7.34.6.Boot Trace
7.34.6.1.AArch64 (BL31)
BL31 prints some lines on the debug console, which will usually look like this(withDEBUG=1
, otherwise only theNOTICE
lines are shown):
...S-DDRFrequency,400MHzNOTICE:BL31:v2.6(debug):v2.6NOTICE:BL31:Built:20:00:00,Dec012021INFO:BL31:PlatformsetupstartINFO:ARMGICv2driverinitializedINFO:BL31:PlatformsetupdoneINFO:BL31:InitializingruntimeservicesINFO:BL31:cortex_a53:CPUworkaroundfor819472wasappliedINFO:BL31:cortex_a53:CPUworkaroundfor824069wasappliedINFO:BL31:cortex_a53:CPUworkaroundfor826319wasappliedINFO:BL31:cortex_a53:CPUworkaroundfor827319wasappliedINFO:BL31:cortex_a53:CPUworkaroundfor835769wasappliedINFO:BL31:cortex_a53:CPUworkaroundfordisable_non_temporal_hintwasappliedINFO:BL31:cortex_a53:CPUworkaroundfor843419wasappliedINFO:BL31:cortex_a53:CPUworkaroundfor1530924wasappliedINFO:BL31:PreparingforEL3exittonormalworldINFO:Entrypointaddress=0x8f600000INFO:SPSR=0x3c9U-Boot2021.10(Dec012021-20:00:00+0000)Qualcomm-DragonBoard410C...
7.34.6.2.AArch32 (BL32/SP_MIN)
BL32/SP_MIN prints some lines on the debug console, which will usually look likethis (withDEBUG=1
, otherwise only theNOTICE
lines are shown):
...S - DDR Frequency, 400 MHzNOTICE: SP_MIN: v2.8(debug):v2.8NOTICE: SP_MIN: Built : 23:03:31, Mar 31 2023INFO: SP_MIN: Platform setup startINFO: ARM GICv2 driver initializedINFO: SP_MIN: Platform setup doneINFO: SP_MIN: Initializing runtime servicesINFO: BL32: cortex_a53: CPU workaround for 819472 was appliedINFO: BL32: cortex_a53: CPU workaround for 824069 was appliedINFO: BL32: cortex_a53: CPU workaround for 826319 was appliedINFO: BL32: cortex_a53: CPU workaround for 827319 was appliedINFO: BL32: cortex_a53: CPU workaround for disable_non_temporal_hint was appliedINFO: SP_MIN: Preparing exit to normal worldINFO: Entry point address = 0x86400000INFO: SPSR = 0x1daAndroid Bootloader - UART_DM Initialized!!![0] welcome to lk...