From 131c65f4293c76f2c9b0b98c62b1937cd0aea4ce Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 17 Mar 2008 03:07:38 -0400 Subject: Restructure bus timing calcs to cope with pkt being deleted by target. --HG-- extra : convert_revision : db8497e73a44f2a06aab121e797e88b4c0c31330 --- src/mem/bus.cc | 44 ++++++++++++++++++++++++-------------------- src/mem/bus.hh | 8 +++++--- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/mem/bus.cc b/src/mem/bus.cc index ff4512aca..3bf1c6cfc 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -110,21 +110,22 @@ const char * Bus::BusFreeEvent::description() const return "bus became available"; } -void Bus::preparePacket(PacketPtr pkt, Tick & headerTime) +Tick Bus::calcPacketTiming(PacketPtr pkt) { - //Bring tickNextIdle up to the present tick - //There is some potential ambiguity where a cycle starts, which might make - //a difference when devices are acting right around a cycle boundary. Using - //a < allows things which happen exactly on a cycle boundary to take up - //only the following cycle. Anything that happens later will have to "wait" - //for the end of that cycle, and then start using the bus after that. + // Bring tickNextIdle up to the present tick. + // There is some potential ambiguity where a cycle starts, which + // might make a difference when devices are acting right around a + // cycle boundary. Using a < allows things which happen exactly on + // a cycle boundary to take up only the following cycle. Anything + // that happens later will have to "wait" for the end of that + // cycle, and then start using the bus after that. if (tickNextIdle < curTick) { tickNextIdle = curTick; if (tickNextIdle % clock != 0) tickNextIdle = curTick - (curTick % clock) + clock; } - headerTime = tickNextIdle + headerCycles * clock; + Tick headerTime = tickNextIdle + headerCycles * clock; // The packet will be sent. Figure out how long it occupies the bus, and // how much of that time is for the first "word", aka bus width. @@ -142,10 +143,17 @@ void Bus::preparePacket(PacketPtr pkt, Tick & headerTime) pkt->firstWordTime = headerTime + clock; pkt->finishTime = headerTime + numCycles * clock; + + return headerTime; } void Bus::occupyBus(Tick until) { + if (until == 0) { + // shortcut for express snoop packets + return; + } + tickNextIdle = until; if (!busIdle.scheduled()) { @@ -190,11 +198,8 @@ Bus::recvTiming(PacketPtr pkt) DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x\n", src, pkt->getDest(), pkt->cmdString(), pkt->getAddr()); - Tick headerTime = 0; - - if (!pkt->isExpressSnoop()) { - preparePacket(pkt, headerTime); - } + Tick headerFinishTime = pkt->isExpressSnoop() ? 0 : calcPacketTiming(pkt); + Tick packetFinishTime = pkt->isExpressSnoop() ? 0 : pkt->finishTime; short dest = pkt->getDest(); int dest_port_id; @@ -243,17 +248,16 @@ Bus::recvTiming(PacketPtr pkt) DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x TGT RETRY\n", src, pkt->getDest(), pkt->cmdString(), pkt->getAddr()); addToRetryList(src_port); - if (!pkt->isExpressSnoop()) { - occupyBus(headerTime); - } + occupyBus(headerFinishTime); return false; } - // send OK, fall through + // send OK, fall through... pkt may have been deleted by + // target at this point, so it should *not* be referenced + // again. We'll set it to NULL here just to be safe. + pkt = NULL; } - if (!pkt->isExpressSnoop()) { - occupyBus(pkt->finishTime); - } + occupyBus(packetFinishTime); // Packet was successfully sent. // Also take care of retries diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 274c02de4..74901d626 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -245,10 +245,12 @@ class Bus : public MemObject */ void addressRanges(AddrRangeList &resp, bool &snoop, int id); - /** Prepare a packet to be sent on the bus. The header finishes at tick - * headerTime + /** Calculate the timing parameters for the packet. Updates the + * firstWordTime and finishTime fields of the packet object. + * Returns the tick at which the packet header is completed (which + * will be all that is sent if the target rejects the packet). */ - void preparePacket(PacketPtr pkt, Tick & headerTime); + Tick calcPacketTiming(PacketPtr pkt); /** Occupy the bus until until */ void occupyBus(Tick until); -- cgit v1.2.3