Skip to content

JTAG debugging for the LS1088A

The Ten64 board has a standard 10-pin, 1.27mm pitch ARM Cortex JTAG debug header, operating at 1.8V. Protocol is standard JTAG (not SWD).

The LS1088 JTAG header is J3, near the SoC on the top of the board. There are no other devices in the chain.

CPU JTAG connector - J3 CPU JTAG connector schematic

The best toolset for low level debugging is NXP's CodeWarrior for Network Applications and the CodeWarrior TAP as CodeWarrior has scripts that can take the SoC out of reset without a bootloader running. CodeWarrior, however, is very pricey (US$3000-5000 annually depending on options) so we also support community tools.

OpenOCD can be used to do post-boot debugging for Trusted Firmware, U-Boot and Linux.

OpenOCD

Get the Configuration here - https://gitlab.com/snippets/1908304

This configuration has been tested with the Dangerous Prototypes BusBlaster v3. You will need an adaptor to convert the 2.54mm pitch connector on the BusBlaster to 1.27mm pitch, such as the Olimex ARM-JTAG-20-10.

Remember to use the "Target Power" option on your adaptor (e.g on the BusBlaster, leave the jumper off).

Note

Reminder: The LS1088 JTAG runs at 1.8V. If you use another voltage you will damage your board!

General tips

Getting breakpoints to work early in the boot process (in TF or U-Boot) can be difficult. The best way around this is to add a long pause/sleep before the code you are trying to debug - then halt the CPU - for example, in before the handoff to U-Boot in ATF.

Tutorial - debugging U-Boot with OpenOCD and gdb

You will need:

  1. An arm64 gdb - if you are not already on a native arm64 host you might find packages in your distribution or you could use the Linaro toolchain.

  2. OpenOCD with support for your target probe

For the BusBlaster you can start OpenOCD with:

.\bin\openocd.exe -f "interface\ftdi\dp_busblaster.cfg" -f .\ls1088a_test.cfg
  1. A compiled u-boot ELF binary (as in u-boot/u-boot) - this is not the same binary that is packaged into Trusted Firmware/BL33 (u-boot normally weighs just under 10MiB, u-boot.bin is around 1.2MiB)

U-Boot debugging is a bit tricky as U-Boot relocates itself after loading - so GDB needs to be told of the relocated offset.

If your board is running, you can use the bdinfo command to get the reloc address:

=> bdinfo
arch_number = 0x0000000000000000
...
TLB addr    = 0x00000000fbdf0000
relocaddr   = 0x00000000fbcd4000
...

You can also discover it from GDB on a running target:

print/x ((gd_t *)$x18)->relocaddr
$1 = 0xfbcd4000

Explanation: x18 is the register where a pointer to U-Boot's global data struct is stored, the relocaddr parameter is inside the global data struct - see the Debugging U-Boot article on denx.de for more information.

and then tell GDB to recognize 0xfbcd6000 as the U-Boot address and load symbols:

symbol-file # to clear the previous symbol definitions
add-symbol-file u-boot 0xfbcd4000

To debug U-Boot before it reaches the command line, you need to use a hardware breakpoint to break the U-Boot entry point (also known as CONFIG_SYS_TEXT_BASE, typically 0x82000000):

  1. Reset the board
  2. Immediately start OpenOCD
  3. On your gdb console, enter:
target extended-remote localhost:3333; thbreak *0x82000000

It might be helpful to add a delay somewhere in Trusted Firmware (before the handover) to give more time to setup the debugger - see this snippet for one possible method.

Reference