Restructure bus timing calcs to cope with pkt being deleted by target.

--HG--
extra : convert_revision : db8497e73a44f2a06aab121e797e88b4c0c31330
This commit is contained in:
Steve Reinhardt 2008-03-17 03:07:38 -04:00
parent 19c367fa8f
commit 131c65f429
2 changed files with 29 additions and 23 deletions

View file

@ -110,21 +110,22 @@ const char * Bus::BusFreeEvent::description() const
return "bus became available"; return "bus became available";
} }
void Bus::preparePacket(PacketPtr pkt, Tick & headerTime) Tick Bus::calcPacketTiming(PacketPtr pkt)
{ {
//Bring tickNextIdle up to the present tick // Bring tickNextIdle up to the present tick.
//There is some potential ambiguity where a cycle starts, which might make // There is some potential ambiguity where a cycle starts, which
//a difference when devices are acting right around a cycle boundary. Using // might make a difference when devices are acting right around a
//a < allows things which happen exactly on a cycle boundary to take up // cycle boundary. Using a < allows things which happen exactly on
//only the following cycle. Anything that happens later will have to "wait" // a cycle boundary to take up only the following cycle. Anything
//for the end of that cycle, and then start using the bus after that. // that happens later will have to "wait" for the end of that
// cycle, and then start using the bus after that.
if (tickNextIdle < curTick) { if (tickNextIdle < curTick) {
tickNextIdle = curTick; tickNextIdle = curTick;
if (tickNextIdle % clock != 0) if (tickNextIdle % clock != 0)
tickNextIdle = curTick - (curTick % clock) + clock; 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 // 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. // 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->firstWordTime = headerTime + clock;
pkt->finishTime = headerTime + numCycles * clock; pkt->finishTime = headerTime + numCycles * clock;
return headerTime;
} }
void Bus::occupyBus(Tick until) void Bus::occupyBus(Tick until)
{ {
if (until == 0) {
// shortcut for express snoop packets
return;
}
tickNextIdle = until; tickNextIdle = until;
if (!busIdle.scheduled()) { if (!busIdle.scheduled()) {
@ -190,11 +198,8 @@ Bus::recvTiming(PacketPtr pkt)
DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x\n", DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x\n",
src, pkt->getDest(), pkt->cmdString(), pkt->getAddr()); src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
Tick headerTime = 0; Tick headerFinishTime = pkt->isExpressSnoop() ? 0 : calcPacketTiming(pkt);
Tick packetFinishTime = pkt->isExpressSnoop() ? 0 : pkt->finishTime;
if (!pkt->isExpressSnoop()) {
preparePacket(pkt, headerTime);
}
short dest = pkt->getDest(); short dest = pkt->getDest();
int dest_port_id; 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", DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x TGT RETRY\n",
src, pkt->getDest(), pkt->cmdString(), pkt->getAddr()); src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
addToRetryList(src_port); addToRetryList(src_port);
if (!pkt->isExpressSnoop()) { occupyBus(headerFinishTime);
occupyBus(headerTime);
}
return false; 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(packetFinishTime);
occupyBus(pkt->finishTime);
}
// Packet was successfully sent. // Packet was successfully sent.
// Also take care of retries // Also take care of retries

View file

@ -245,10 +245,12 @@ class Bus : public MemObject
*/ */
void addressRanges(AddrRangeList &resp, bool &snoop, int id); void addressRanges(AddrRangeList &resp, bool &snoop, int id);
/** Prepare a packet to be sent on the bus. The header finishes at tick /** Calculate the timing parameters for the packet. Updates the
* headerTime * 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 */ /** Occupy the bus until until */
void occupyBus(Tick until); void occupyBus(Tick until);