# Linux Kernel Module Cheat

###### 24.22.4.2.6. TimingSimpleCPU analysis #6

Schedules `DRAMCtrl::processNextReqEvent` through:

    EventManager::schedule
    DRAMCtrl::addToReadQueue
    DRAMCtrl::recvTimingReq
    DRAMCtrl::MemoryPort::recvTimingReq
    TimingRequestProtocol::sendReq
    MasterPort::sendTimingReq
    CoherentXBar::recvTimingReq
    CoherentXBar::CoherentXBarSlavePort::recvTimingReq
    TimingRequestProtocol::sendReq
    MasterPort::sendTimingReq
    TimingSimpleCPU::sendFetch
    TimingSimpleCPU::FetchTranslation::finish
    ArmISA::TLB::translateComplete
    ArmISA::TLB::translateTiming
    ArmISA::TLB::translateTiming
    TimingSimpleCPU::fetch

The event loop has started, and magic initialization schedulings are not happening anymore: now every event is being scheduled from another event:

From the trace, we see that we are already running from the event queue under `TimingSimpleCPU::fetch` as expected.

From the backtrace we see the tortuous path that the data request takes, going through:

- `ArmISA::TLB`

- `CoherentXBar`

- `DRAMCtrl`

This matches the `config.ini` system image, since we see that the request goes through the `CoherentXBar` before reaching memory, like all other CPU memory accesses, see also: gem5 crossbar interconnect.

The scheduling happens at frame `DRAMCtrl::addToReadQueue`:

         // If we are not already scheduled to get a request out of the
         // queue, do so now
         if (!nextReqEvent.scheduled()) {
             DPRINTF(DRAM, "Request scheduled immediately\n");
             schedule(nextReqEvent, curTick());
         }

From this we deduce that the DRAM has a request queue of some sort, and that the fetch:

- has added a read request to that queue

- and has made a future request to read from the queue

The signature of the function is:

    DRAMCtrl::addToReadQueue(PacketPtr pkt, unsigned int pktCount)

where `PacketPtr` is of `class `Packet`, and so clearly the packet is coming from above.

From:

    p/x *pkt

we see:

    addr = 0x78

which from TimingSimpleCPU analysis #5 we know is the physical address of the ELF entry point.

Communication goes through certain components via the `class Port` interface, e.g. at `TimingSimpleCPU::sendFetch` a call is made to send the packet forward:

    icachePort.sendTimingReq(ifetch_pkt)

which ends up calling:

    peer->recvTimingReq(pkt);

to reach the receiving side:

    CoherentXBar::CoherentXBarSlavePort::recvTimingReq

Ports are also used to connect the XBar and the DRAM.

We will then see that at TimingSimpleCPU analysis #20 a reply packet will come back through the port interface down to the icache port, and only then does the decoding and execution happen.