diff options
-rw-r--r-- | src/dev/io_device.cc | 8 | ||||
-rw-r--r-- | src/dev/pcidev.cc | 12 | ||||
-rw-r--r-- | src/mem/bridge.cc | 17 | ||||
-rw-r--r-- | src/mem/simple_mem.cc | 29 | ||||
-rw-r--r-- | src/mem/simple_mem.hh | 4 |
5 files changed, 52 insertions, 18 deletions
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 74ab8c3b3..daa939d8f 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012, 2015 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -54,12 +54,14 @@ PioPort::PioPort(PioDevice *dev) Tick PioPort::recvAtomic(PacketPtr pkt) { - // @todo: We need to pay for this and not just zero it out + // technically the packet only reaches us after the header delay, + // and typically we also need to deserialise any payload + Tick receive_delay = pkt->headerDelay + pkt->payloadDelay; pkt->headerDelay = pkt->payloadDelay = 0; const Tick delay(pkt->isRead() ? device->read(pkt) : device->write(pkt)); assert(pkt->isResponse() || pkt->isError()); - return delay; + return delay + receive_delay; } AddrRangeList diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index 4126141b9..7b542ab1c 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 ARM Limited + * Copyright (c) 2013, 2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -79,9 +79,15 @@ PciDevice::PciConfigPort::recvAtomic(PacketPtr pkt) { assert(pkt->getAddr() >= configAddr && pkt->getAddr() < configAddr + PCI_CONFIG_SIZE); - // @todo someone should pay for this + + // technically the packet only reaches us after the header delay, + // and typically we also need to deserialise any payload + Tick receive_delay = pkt->headerDelay + pkt->payloadDelay; pkt->headerDelay = pkt->payloadDelay = 0; - return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt); + + const Tick delay(pkt->isRead() ? device->readConfig(pkt) : + device->writeConfig(pkt)); + return delay + receive_delay; } AddrRangeList diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 855f39de3..1f7d1d43a 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -136,10 +136,14 @@ Bridge::BridgeMasterPort::recvTimingResp(PacketPtr pkt) DPRINTF(Bridge, "Request queue size: %d\n", transmitList.size()); - // @todo: We need to pay for this and not just zero it out + // technically the packet only reaches us after the header delay, + // and typically we also need to deserialise any payload (unless + // the two sides of the bridge are synchronous) + Tick receive_delay = pkt->headerDelay + pkt->payloadDelay; pkt->headerDelay = pkt->payloadDelay = 0; - slavePort.schedTimingResp(pkt, bridge.clockEdge(delay)); + slavePort.schedTimingResp(pkt, bridge.clockEdge(delay) + + receive_delay); return true; } @@ -191,10 +195,15 @@ Bridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt) } if (!retryReq) { - // @todo: We need to pay for this and not just zero it out + // technically the packet only reaches us after the header + // delay, and typically we also need to deserialise any + // payload (unless the two sides of the bridge are + // synchronous) + Tick receive_delay = pkt->headerDelay + pkt->payloadDelay; pkt->headerDelay = pkt->payloadDelay = 0; - masterPort.schedTimingReq(pkt, bridge.clockEdge(delay)); + masterPort.schedTimingReq(pkt, bridge.clockEdge(delay) + + receive_delay); } } diff --git a/src/mem/simple_mem.cc b/src/mem/simple_mem.cc index 639ccbe31..d4dbe1946 100644 --- a/src/mem/simple_mem.cc +++ b/src/mem/simple_mem.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 ARM Limited + * Copyright (c) 2010-2013, 2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -116,7 +116,10 @@ SimpleMemory::recvTimingReq(PacketPtr pkt) return false; } - // @todo someone should pay for this + // technically the packet only reaches us after the header delay, + // and since this is a memory controller we also need to + // deserialise the payload before performing any write operation + Tick receive_delay = pkt->headerDelay + pkt->payloadDelay; pkt->headerDelay = pkt->payloadDelay = 0; // update the release time according to the bandwidth limit, and @@ -150,10 +153,24 @@ SimpleMemory::recvTimingReq(PacketPtr pkt) // recvAtomic() should already have turned packet into // atomic response assert(pkt->isResponse()); - // to keep things simple (and in order), we put the packet at - // the end even if the latency suggests it should be sent - // before the packet(s) before it - packetQueue.emplace_back(pkt, curTick() + getLatency()); + + Tick when_to_send = curTick() + receive_delay + getLatency(); + + // typically this should be added at the end, so start the + // insertion sort with the last element, also make sure not to + // re-order in front of some existing packet with the same + // address, the latter is important as this memory effectively + // hands out exclusive copies (shared is not asserted) + auto i = packetQueue.end(); + --i; + while (i != packetQueue.begin() && when_to_send < i->tick && + i->pkt->getAddr() != pkt->getAddr()) + --i; + + // emplace inserts the element before the position pointed to by + // the iterator, so advance it one step + packetQueue.emplace(++i, pkt, when_to_send); + if (!retryResp && !dequeueEvent.scheduled()) schedule(dequeueEvent, packetQueue.back().tick); } else { diff --git a/src/mem/simple_mem.hh b/src/mem/simple_mem.hh index d19de7608..23cd3c80d 100644 --- a/src/mem/simple_mem.hh +++ b/src/mem/simple_mem.hh @@ -49,7 +49,7 @@ #ifndef __SIMPLE_MEMORY_HH__ #define __SIMPLE_MEMORY_HH__ -#include <deque> +#include <list> #include "mem/abstract_mem.hh" #include "mem/port.hh" @@ -125,7 +125,7 @@ class SimpleMemory : public AbstractMemory * actual memory access. Note that this is where the packet spends * the memory latency. */ - std::deque<DeferredPacket> packetQueue; + std::list<DeferredPacket> packetQueue; /** * Bandwidth in ticks per byte. The regulation affects the |