24.22.4.2.5. TimingSimpleCPU analysis #5

Executes TimingSimpleCPU::fetch().

The log shows that event ID 43 is now executing: we had previously seen event 43 get scheduled and had analyzed it to be the initial fetch.

We can step into TimingSimpleCPU::fetch() to confirm that the expected ELF entry point is being fetched. We can inspect the ELF with:

./run-toolchain --arch aarch64 readelf -- \
  -h "$(./getvar --arch aarch64 userland_build_dir)/arch/aarch64/freestanding/linux/hello.out"

which contains:

  Entry point address:               0x400078

and by the time we go past:

TimingSimpleCPU::fetch()
{
    ...
    if (needToFetch) {
        ...
        setupFetchRequest(ifetch_req);
        DPRINTF(SimpleCPU, "Translating address %#x\n", ifetch_req->getVaddr());
        thread->itb->translateTiming(ifetch_req, thread->getTC(),
                &fetchTranslation, BaseTLB::Execute);

BaseSimpleCPU::setupFetchRequest sets up the fetch of the expected entry point by reading the PC:

p/x ifetch_req->getVaddr()

Still during the execution of the fetch, execution then moves into the address translation ArmISA::TLB::translateTiming, and after a call to:

TLB::translateSe

the packet now contains the physical address:

_paddr = 0x78

so we deduce that the virtual address 0x400078 maps to the physical address 0x78. But of course, let me log that for you by adding --trace MMU:

      0: MMU: system.cpu.workload: Translating: 0x400078->0x78

If we try --trace DRAM we can see:

      0: DRAM: system.mem_ctrls: recvTimingReq: request ReadReq addr 120 size 4

where 120 == 0x78 (it logs addresses in decimal? Really??) and the size 4 which is the instruction width.

Now that we are here, we might as well learn how to log the data that was fetched from DRAM.

Fist we determine the expected bytes from the disassembly:

./disas --arch aarch64 --userland userland/arch/aarch64/freestanding/linux/hello.S _start

which shows us the initial instruction encodings near the entry point _start:

   0x0000000000400078 <+0>:     20 00 80 d2     mov     x0, #0x1                        // #1
   0x000000000040007c <+4>:     e1 00 00 10     adr     x1, 0x400098 <msg>

Now, TODO :-) The DRAM logs don’t contain data. Maybe this can be done with CommMonitor, but it is no exposed on fs.py