Last edited 6 months ago

How to debug TF-A BL2

Applicable for STM32MP13x lines, STM32MP15x lines

1. Article Purpose[edit | edit source]

This article explains how to debug TF-A BL2 firmware.
Debug is specifically linked to the TrustZone environment.

There are two main ways to debug TF-A, using traces inside the code, or by using JTAG to access the secure world. The focus here is on the solution integrated in OpenSTLinux: debug over gdb (ST-Link or JTAG based)

2. Debugging[edit | edit source]

2.1. TF-A Version number[edit | edit source]

The starting point for debugging is to identify the TF-A BL2 version used in the target. Debug and release versions are displayed on the console with the following format:

NOTICE: BL2: v2.8(debug):<tag>
  • v2.8 is the TF-A BL2 version used.
  • (debug) : Build mode enable
  • <tag> : Git reference resulting from the git describe command at build time

On software delivered by STMicroelectronics, and not from TrustedFirmware.org, there is extra information:

NOTICE: BL2: v2.8-<platform>-<rX.Y>(debug):<tag>(<sha1>)
  • platform: either stm32mp1 or stm32mp2
  • rX.Y: STMicroelectronics release version
  • sha1: git SHA1

2.2. Debug with traces[edit | edit source]

TF-A allows RELEASE and DEBUG modes to be enabled:

  • RELEASE mode builds with default LOG_LEVEL to 20, which only prints ERROR and NOTICE traces
  • DEBUG mode enables the -g build flag (for debug build object), and defaults LOG_LEVEL to 40

With the debug LOG_LEVEL, you can add console traces such as ERROR, NOTICE, WARNING or INFO. Please refer to include/common/debug.h .

Warning white.png Warning
You cannot build code with LOG_LEVEL set to 50 (the highest level); there are too many traces and TF-A does not fit in the SYSRAM. If required, change some VERBOSE settings to INFO.
Another possibility is to add the following lines at the beginning of the .c file, after the includes:
   #undef VERBOSE
   #define VERBOSE INFO

For both modes, you must ensure that the UART is properly configured:

  • BL2: UART traces are enabled by default

Traces and errors are available on the console defined in the chosen node of the device tree by the stdout-path property:

chosen {
        stdout-path = "serial0:115200n8";
};

Traces will only be available after the console has been fully registered. Prior to that, the traces are not displayed except panic messages, so it is recommended to use a debugger. Early traces can be enabled with the compilation flag: STM32MP_EARLY_CONSOLE.

The early traces and panic messages are displayed through the crash console. It uses hard-coded UART settings.

2.2.1. UART early console configuration[edit | edit source]

The UART configuration is retrieved from device tree. But for early console, or crash console, some parameters have to be hard-coded. Those parameters are in plat/st/stm32mp1/stm32mp1_def.h for STM32MP1 series and in plat/st/stm32mp1/stm32mp2_def.h for STM32MP2 series, after the comment:

/* For UART crash console */

Here is an example, for STMicroelectronics STM32MP1 series boards, using UART4, on HSI clock (64MHz), with TX signal on GPIOD6 pin, alternate 8.

#define STM32MP_DEBUG_USART_BASE	UART4_BASE
#define STM32MP_DEBUG_USART_CLK_FRQ	64000000 
#define DEBUG_UART_TX_GPIO_BANK_ADDRESS	GPIOD_BASE
#define DEBUG_UART_TX_GPIO_BANK_CLK_REG	RCC_MP_S_AHB4ENSETR
#define DEBUG_UART_TX_GPIO_BANK_CLK_EN	RCC_MP_S_AHB4ENSETR_GPIODEN
#define DEBUG_UART_TX_GPIO_PORT		6
#define DEBUG_UART_TX_GPIO_ALTERNATE	8
#define DEBUG_UART_TX_CLKSRC_REG	RCC_UART4CKSELR
#define DEBUG_UART_TX_CLKSRC		RCC_UART4CKSELR_HSI
#define DEBUG_UART_TX_EN_REG		RCC_MP_APB1ENSETR
#define DEBUG_UART_TX_EN		RCC_MP_APB1ENSETR_UART4EN
#define DEBUG_UART_RST_REG		RCC_APB1RSTSETR
#define DEBUG_UART_RST_BIT		RCC_APB1RSTSETR_UART4RST

Those parameters may then have to be adapted, depending on board configuration.

To enable early console, use this build option:

  • STM32MP_EARLY_CONSOLE=1

2.3. Debug with GDB[edit | edit source]

See Wrapper for FSBL images for more information on how to debug TF-A BL2 with a debugger.