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.