diff options
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r-- | src/mem/bus.cc | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc index ff4512aca..2eb823051 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -97,34 +97,39 @@ Bus::init() intIter->second->sendStatusChange(Port::RangeChange); } -Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) : Event(&mainEventQueue), bus(_bus) +Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) + : bus(_bus) {} -void Bus::BusFreeEvent::process() +void +Bus::BusFreeEvent::process() { bus->recvRetry(-1); } -const char * Bus::BusFreeEvent::description() const +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,17 +147,20 @@ 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; + reschedule(busIdle, tickNextIdle, true); - if (!busIdle.scheduled()) { - busIdle.schedule(tickNextIdle); - } else { - busIdle.reschedule(tickNextIdle); - } DPRINTF(Bus, "The bus is now occupied from tick %d to %d\n", curTick, tickNextIdle); } @@ -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 @@ -289,7 +293,7 @@ Bus::recvRetry(int id) //Burn a cycle for the missed grant. tickNextIdle += clock; - busIdle.reschedule(tickNextIdle, true); + reschedule(busIdle, tickNextIdle, true); } } //If we weren't able to drain before, we might be able to now. @@ -327,10 +331,10 @@ Bus::findPort(Addr addr) if (responderSet) { panic("Unable to find destination for addr (user set default " - "responder): %#llx", addr); + "responder): %#llx\n", addr); } else { DPRINTF(Bus, "Unable to find destination for addr: %#llx, will use " - "default port", addr); + "default port\n", addr); return defaultId; } @@ -519,9 +523,12 @@ Bus::recvStatusChange(Port::Status status, int id) for (iter = ranges.begin(); iter != ranges.end(); iter++) { DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n", iter->start, iter->end, id); - if (portMap.insert(*iter, id) == portMap.end()) - panic("Two devices with same range\n"); - + if (portMap.insert(*iter, id) == portMap.end()) { + int conflict_id = portMap.find(*iter)->second; + fatal("%s has two ports with same range:\n\t%s\n\t%s\n", + name(), interfaces[id]->getPeer()->name(), + interfaces[conflict_id]->getPeer()->name()); + } } } DPRINTF(MMU, "port list has %d entries\n", portMap.size()); |