summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@gmail.com>2008-03-17 03:07:38 -0400
committerSteve Reinhardt <stever@gmail.com>2008-03-17 03:07:38 -0400
commit131c65f4293c76f2c9b0b98c62b1937cd0aea4ce (patch)
treefa91f138d07da92c2b82fa6c3ef7436dbeab4169
parent19c367fa8fa0c330676c1b7aacb532b8871164cf (diff)
downloadgem5-131c65f4293c76f2c9b0b98c62b1937cd0aea4ce.tar.xz
Restructure bus timing calcs to cope with pkt being deleted by target.
--HG-- extra : convert_revision : db8497e73a44f2a06aab121e797e88b4c0c31330
-rw-r--r--src/mem/bus.cc44
-rw-r--r--src/mem/bus.hh8
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);