#include "base/misc.hh"
#include "base/trace.hh"
#include "mem/bus.hh"
-#include "params/Bus.hh"
Port *
Bus::getPort(const std::string &if_name, int idx)
bus->recvRetry(-1);
}
-const char * Bus::BusFreeEvent::description()
+const char * Bus::BusFreeEvent::description() const
{
return "bus became available";
}
// The first word will be delivered after the current tick, the delivery
// of the address if any, and one bus cycle to deliver the data
- pkt->firstWordTime =
- tickNextIdle +
- pkt->isRequest() ? clock : 0 +
- clock;
+ pkt->firstWordTime = tickNextIdle + (pkt->isRequest() ? clock : 0) + clock;
//Advance it numCycles bus cycles.
//XXX Should this use the repeated addition trick as well?
Bus::recvTiming(PacketPtr pkt)
{
short src = pkt->getSrc();
- DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
- src, pkt->getDest(), pkt->getAddr(), pkt->cmdString());
BusPort *src_port;
if (src == defaultId)
(retryList.size() && (!inRetry || src_port != retryList.front()))))
{
addToRetryList(src_port);
- DPRINTF(Bus, "recvTiming: Bus is busy, returning false\n");
+ DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x BUSY\n",
+ src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
return false;
}
+ DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x\n",
+ src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
+
if (!pkt->isExpressSnoop()) {
occupyBus(pkt);
}
dest_port_id = findPort(pkt->getAddr());
dest_port = (dest_port_id == defaultId) ?
defaultPort : interfaces[dest_port_id];
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end();
- s_iter++) {
+ SnoopIter s_end = snoopPorts.end();
+ for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
BusPort *p = *s_iter;
if (p != dest_port && p != src_port) {
-#ifndef NDEBUG
// cache is not allowed to refuse snoop
- bool success = p->sendTiming(pkt);
+ bool success M5_VAR_USED = p->sendTiming(pkt);
assert(success);
-#else
- // avoid unused variable warning
- p->sendTiming(pkt);
-#endif
}
}
} else {
if (dest_port_id == src) {
// Must be forwarded snoop up from below...
assert(dest == Packet::Broadcast);
+ assert(src != defaultId); // catch infinite loops
} else {
// send to actual target
if (!dest_port->sendTiming(pkt)) {
// Packet not successfully sent. Leave or put it on the retry list.
// illegal to block responses... can lead to deadlock
assert(!pkt->isResponse());
- DPRINTF(Bus, "Adding2 a retry to RETRY list %d\n", src);
+ DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x TGT RETRY\n",
+ src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
addToRetryList(src_port);
return false;
}
// Check if this matches the default range
if (dest_id == -1) {
- for (AddrRangeIter iter = defaultRange.begin();
- iter != defaultRange.end(); iter++) {
- if (*iter == addr) {
+ AddrRangeIter a_end = defaultRange.end();
+ for (AddrRangeIter i = defaultRange.begin(); i != a_end; i++) {
+ if (*i == addr) {
DPRINTF(Bus, " found addr %#llx on default\n", addr);
return defaultId;
}
void
Bus::recvFunctional(PacketPtr pkt)
{
- DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n",
- pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
+ if (!pkt->isPrint()) {
+ // don't do DPRINTFs on PrintReq as it clutters up the output
+ DPRINTF(Bus,
+ "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n",
+ pkt->getSrc(), pkt->getDest(), pkt->getAddr(),
+ pkt->cmdString());
+ }
assert(pkt->getDest() == Packet::Broadcast);
int port_id = findPort(pkt->getAddr());
assert(pkt->isRequest()); // hasn't already been satisfied
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end();
- s_iter++) {
+ SnoopIter s_end = snoopPorts.end();
+ for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
BusPort *p = *s_iter;
if (p != port && p->getId() != src_id) {
p->sendFunctional(pkt);
bool snoops;
AddrRangeIter iter;
+ if (inRecvStatusChange.count(id))
+ return;
+ inRecvStatusChange.insert(id);
+
assert(status == Port::RangeChange &&
"The other statuses need to be implemented.");
if (id != defaultId && defaultPort)
defaultPort->sendStatusChange(Port::RangeChange);
+ inRecvStatusChange.erase(id);
}
void
int max_bs = -1;
- for (PortIter portIter = portMap.begin();
- portIter != portMap.end(); portIter++) {
- int tmp_bs = interfaces[portIter->second]->peerBlockSize();
+ PortIter p_end = portMap.end();
+ for (PortIter p_iter = portMap.begin(); p_iter != p_end; p_iter++) {
+ int tmp_bs = interfaces[p_iter->second]->peerBlockSize();
if (tmp_bs > max_bs)
max_bs = tmp_bs;
}
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end(); s_iter++) {
+ SnoopIter s_end = snoopPorts.end();
+ for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
int tmp_bs = (*s_iter)->peerBlockSize();
if (tmp_bs > max_bs)
max_bs = tmp_bs;
//We should check that we're not "doing" anything, and that noone is
//waiting. We might be idle but have someone waiting if the device we
//contacted for a retry didn't actually retry.
- if (curTick >= tickNextIdle && retryList.size() == 0) {
- return 0;
- } else {
+ if (retryList.size() || (curTick < tickNextIdle && busIdle.scheduled())) {
drainEvent = de;
return 1;
}
+ return 0;
}
void
Bus *
BusParams::create()
{
- return new Bus(name, bus_id, clock, width, responder_set, block_size);
+ return new Bus(this);
}