23.9.8.2. gem5 ExecAll trace format

This debug flag traces all instructions.

The output format is of type:

25007000: system.cpu T0 : @start_kernel    : stp
25007000: system.cpu T0 : @start_kernel.0  :   addxi_uop   ureg0, sp, #-112 : IntAlu :  D=0xffffff8008913f90
25007500: system.cpu T0 : @start_kernel.1  :   strxi_uop   x29, [ureg0] : MemWrite :  D=0x0000000000000000 A=0xffffff8008913f90
25008000: system.cpu T0 : @start_kernel.2  :   strxi_uop   x30, [ureg0, #8] : MemWrite :  D=0x0000000000000000 A=0xffffff8008913f98
25008500: system.cpu T0 : @start_kernel.3  :   addxi_uop   sp, ureg0, #0 : IntAlu :  D=0xffffff8008913f90

There are two types of lines:

Breakdown:

  • 25007500: time count in some unit. Note how the microops execute at further timestamps.

  • system.cpu: distinguishes between CPUs when there are more than one. For example, running Section 33.10.3, “ARM baremetal multicore” with two cores produces system.cpu0 and system.cpu1

  • T0: thread number. TODO: hyperthread? How to play with it?

    config.ini has --param 'system.multi_thread = True' --param 'system.cpu[0].numThreads = 2', but in ARM baremetal multicore the first one alone does not produce T1, and with the second one simulation blows up with:

    fatal: fatal condition interrupts.size() != numThreads occurred: CPU system.cpu has 1 interrupt controllers, but is expecting one per thread (2)
  • @start_kernel: we are in the start_kernel function. Awesome feature! Implemented with libelf https://sourceforge.net/projects/elftoolchain/ copy pasted in-tree ext/libelf. To get raw addresses, remove the ExecSymbol, which is enabled by Exec. This can be done with Exec,-ExecSymbol.

  • .1 as in @start_kernel.1: index of the gem5 microops

  • stp: instruction disassembly. Note however that the disassembly of many instructions are very broken as of 2019q2, and you can’t just trust them blindly.

  • strxi_uop x29, [ureg0]: microop disassembly.

  • MemWrite : D=0x0000000000000000 A=0xffffff8008913f90: a memory write microop:

    • D stands for data, and represents the value that was written to memory or to a register

    • A stands for address, and represents the address to which the value was written. It only shows when data is being written to memory, but not to registers.

The best way to verify all of this is to write some baremetal code