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
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue