Restructure bus timing calcs to cope with pkt being deleted by target.
--HG-- extra : convert_revision : db8497e73a44f2a06aab121e797e88b4c0c31330
This commit is contained in:
parent
19c367fa8f
commit
131c65f429
2 changed files with 29 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue