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
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.
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
.
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!
Figured I post it here as well. I get
tricore-tdep.c:38:10: fatal error: 'opcodes/tricore-dis.h' file not found
errorwhen running
make
after./configure --disable-werror --target=tricore
trying to compile tricore-gdb