Skip to content

Instantly share code, notes, and snippets.

@fastboatster
Forked from bri3d/qemu-tricore.md
Last active May 27, 2022 07:05
Show Gist options
  • Save fastboatster/a50ef3b8a57270a5f5d02386d553bcc0 to your computer and use it in GitHub Desktop.
Save fastboatster/a50ef3b8a57270a5f5d02386d553bcc0 to your computer and use it in GitHub Desktop.
Getting TriCore qemu + gdb working!

Getting QEMU

The mainline release of QEMU includes working simulation of Tricore. Both TC1.3 and TC1.6 CPU instruction sets are supported. No peripherals are implemented.

However, the mainline QEMU's "triboard" based machine specification is insufficient for most ECU use cases as it does not define the correct memory regions or aliasing.

I have an example of setup for Simos18 here: https://github.com/bri3d/qemu/tree/tricore-simos18 . The kernel load code (and constants) as well as the hardcoded entry point are actually unnecessary with the use of the QEMU "loader" device, documented below.

So, to get started, first we simply build QEMU for Tricore: ./configure --target-list=tricore-softmmu && make . You should now have a qemu-system-tricore binary, provided your dependencies were set up correctly (the QEMU documentation is good for this).

Next, we want to start QEMU in "single-step" mode (which tells the code generator not to group instructions), with the debugger ON, and the CPU halted. We can use the loader plugin to add whichever flash segments we would like at whichever addresses we would like as well. Here's an example of loading the Calibration block and SBOOT for Simos18, which I used while understanding how the RSA process constructs the data being signed.

../qemu/build/qemu-system-tricore -machine tricore_s18 -kernel simos18_flash.bin.sboot -device loader,file=simos18_flash.bin.cal,addr=0x80800000 -singlestep -s -S

Updates to compile Volumit's Tricore QEMU fork on M1 Mac running MacOS Monterey

  • clone qemu from https://github.com/volumit/qemu.git
  • install ninja build system: pip install ninja
  • after ./configure --target-list=tricore-softmmu && make is run, there's going to be a bunch of errors from the compilation of qemu/disas/libvixl/vixl/utils.h header file related to isnan and numeric_limits functions/templates. Need to replace std::isnan calls in this file with isnan and replace #include <cmath> with #include <math.h>. may also need to do export CPATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include and check if xcrun --show-sdk-path shows /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk or otherwise do sudo xcode-select -s /Library/Developer/CommandLineTools

Getting GDB

Tricore GDBs seem hard to come by - it seems that Hightec have removed GDB from their free toolchain. For this, I simply used this mysterious GitHub project: https://github.com/Gigallith/gdb-tricore . It compiled right up without any fuss using ./configure --disable-werror --target=tricore for me and produced a gdb/gdb binary with Tricore target support.

Update

Use Volumit's GDB fork instead: https://github.com/volumit/gdb-tricore.git

Hooking it all up, nuances, etc.

OK, so we have a running qemu waiting on a gdb connection - we can connect to it easily by firing up gdb and running target remote localhost:1234 . Intuitively, we want to just set $pc to the code we wish to inspect and let it run wild, but there's a catch:

Experienced TriCore engineers will remember that Tricore operates using "context states," used for task switching, and that the low registers are usually used as global offset registers (a0, a8, a9 etc.). And, sure enough, we need to configure this Context Store system before we can issue a call or ret instruction - otherwise, qemu will correctly emulate the "unconfigured context system" traps and jump into somewhere you don't expect in your trap vector table, instead of issuing a call/ret.

The easy way to do this is to simply jump through the initialization code for whatever task you'd like to debug. In the case of Simos18 SBOOT, this looks like:

set $pc=0x80007672
break *0x80007862
continue

Once we have the context registers and globals configured correctly, we're ready to jump into whatever code we'd like, using set $pc= and break .

Ghidra

And yes, you can point Ghidra's Debugger branch at this Tricore GDB and have Tricore debugging in Ghidra. A totally free and open source Tricore debug toolchain - pretty cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment