projects
/
gem5.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ruby: move stall and wakeup functions to AbstractController
[gem5.git]
/
src
/
mem
/
coherent_bus.cc
diff --git
a/src/mem/coherent_bus.cc
b/src/mem/coherent_bus.cc
index 9566549814ca16518b73660e42a934a759af2268..0166872a78f2fd99c534d92fc4abf9ac30e6438b 100644
(file)
--- a/
src/mem/coherent_bus.cc
+++ b/
src/mem/coherent_bus.cc
@@
-52,15
+52,19
@@
#include "debug/BusAddrRanges.hh"
#include "debug/CoherentBus.hh"
#include "mem/coherent_bus.hh"
#include "debug/BusAddrRanges.hh"
#include "debug/CoherentBus.hh"
#include "mem/coherent_bus.hh"
+#include "sim/system.hh"
CoherentBus::CoherentBus(const CoherentBusParams *p)
CoherentBus::CoherentBus(const CoherentBusParams *p)
- : BaseBus(p), layer(*this, ".layer", p->clock)
+ : BaseBus(p), reqLayer(*this, ".reqLayer"),
+ respLayer(*this, ".respLayer"),
+ snoopRespLayer(*this, ".snoopRespLayer"),
+ system(p->system)
{
// create the ports based on the size of the master and slave
// vector ports, and the presence of the default port, the ports
// are enumerated starting from zero
for (int i = 0; i < p->port_master_connection_count; ++i) {
{
// create the ports based on the size of the master and slave
// vector ports, and the presence of the default port, the ports
// are enumerated starting from zero
for (int i = 0; i < p->port_master_connection_count; ++i) {
- std::string portName = csprintf("%s
-p%d
", name(), i);
+ std::string portName = csprintf("%s
.master[%d]
", name(), i);
MasterPort* bp = new CoherentBusMasterPort(portName, *this, i);
masterPorts.push_back(bp);
}
MasterPort* bp = new CoherentBusMasterPort(portName, *this, i);
masterPorts.push_back(bp);
}
@@
-69,7
+73,7
@@
CoherentBus::CoherentBus(const CoherentBusParams *p)
// our corresponding master port
if (p->port_default_connection_count) {
defaultPortID = masterPorts.size();
// our corresponding master port
if (p->port_default_connection_count) {
defaultPortID = masterPorts.size();
- std::string portName =
csprintf("%s-default", name())
;
+ std::string portName =
name() + ".default"
;
MasterPort* bp = new CoherentBusMasterPort(portName, *this,
defaultPortID);
masterPorts.push_back(bp);
MasterPort* bp = new CoherentBusMasterPort(portName, *this,
defaultPortID);
masterPorts.push_back(bp);
@@
-77,7
+81,7
@@
CoherentBus::CoherentBus(const CoherentBusParams *p)
// create the slave ports, once again starting at zero
for (int i = 0; i < p->port_slave_connection_count; ++i) {
// create the slave ports, once again starting at zero
for (int i = 0; i < p->port_slave_connection_count; ++i) {
- std::string portName = csprintf("%s
-p%d
", name(), i);
+ std::string portName = csprintf("%s
.slave[%d]
", name(), i);
SlavePort* bp = new CoherentBusSlavePort(portName, *this, i);
slavePorts.push_back(bp);
}
SlavePort* bp = new CoherentBusSlavePort(portName, *this, i);
slavePorts.push_back(bp);
}
@@
-88,6
+92,9
@@
CoherentBus::CoherentBus(const CoherentBusParams *p)
void
CoherentBus::init()
{
void
CoherentBus::init()
{
+ // the base class is responsible for determining the block size
+ BaseBus::init();
+
// iterate over our slave ports and determine which of our
// neighbouring master ports are snooping and add them as snoopers
for (SlavePortConstIter p = slavePorts.begin(); p != slavePorts.end();
// iterate over our slave ports and determine which of our
// neighbouring master ports are snooping and add them as snoopers
for (SlavePortConstIter p = slavePorts.begin(); p != slavePorts.end();
@@
-115,7
+122,7
@@
CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
// test if the bus should be considered occupied for the current
// port, and exclude express snoops from the check
// test if the bus should be considered occupied for the current
// port, and exclude express snoops from the check
- if (!is_express_snoop && !
l
ayer.tryTiming(src_port)) {
+ if (!is_express_snoop && !
reqL
ayer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@
-128,11
+135,11
@@
CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
// set the source port for routing of the response
pkt->setSrc(slave_port_id);
// set the source port for routing of the response
pkt->setSrc(slave_port_id);
-
Tick headerFinishTime = is_express_snoop ? 0 :
calcPacketTiming(pkt);
- Tick packetFinishTime =
is_express_snoop ? 0 : pkt->finishTime
;
+ calcPacketTiming(pkt);
+ Tick packetFinishTime =
pkt->busLastWordDelay + curTick()
;
// uncacheable requests need never be snooped
// uncacheable requests need never be snooped
- if (!pkt->req->isUncacheable()) {
+ if (!pkt->req->isUncacheable()
&& !system->bypassCaches()
) {
// the packet is a memory-mapped request and should be
// broadcasted to our snoopers but the source
forwardTiming(pkt, slave_port_id);
// the packet is a memory-mapped request and should be
// broadcasted to our snoopers but the source
forwardTiming(pkt, slave_port_id);
@@
-172,14
+179,17
@@
CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
if (add_outstanding)
outstandingReq.erase(pkt->req);
if (add_outstanding)
outstandingReq.erase(pkt->req);
+ // undo the calculation so we can check for 0 again
+ pkt->busFirstWordDelay = pkt->busLastWordDelay = 0;
+
DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x RETRY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
// update the bus state and schedule an idle event
DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x RETRY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
// update the bus state and schedule an idle event
-
layer.failedTiming(src_port, headerFinishTime
);
+
reqLayer.failedTiming(src_port, clockEdge(Cycles(headerCycles))
);
} else {
// update the bus state and schedule an idle event
} else {
// update the bus state and schedule an idle event
-
l
ayer.succeededTiming(packetFinishTime);
+
reqL
ayer.succeededTiming(packetFinishTime);
}
}
}
}
@@
-194,7
+204,7
@@
CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
// test if the bus should be considered occupied for the current
// port
// test if the bus should be considered occupied for the current
// port
- if (!
l
ayer.tryTiming(src_port)) {
+ if (!
respL
ayer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@
-204,7
+214,7
@@
CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
src_port->name(), pkt->cmdString(), pkt->getAddr());
calcPacketTiming(pkt);
src_port->name(), pkt->cmdString(), pkt->getAddr());
calcPacketTiming(pkt);
- Tick packetFinishTime = pkt->
finishTime
;
+ Tick packetFinishTime = pkt->
busLastWordDelay + curTick()
;
// the packet is a normal response to a request that we should
// have seen passing through the bus
// the packet is a normal response to a request that we should
// have seen passing through the bus
@@
-221,7
+231,7
@@
CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
// deadlock
assert(success);
// deadlock
assert(success);
-
l
ayer.succeededTiming(packetFinishTime);
+
respL
ayer.succeededTiming(packetFinishTime);
return true;
}
return true;
}
@@
-258,7
+268,7
@@
CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
// test if the bus should be considered occupied for the current
// port
// test if the bus should be considered occupied for the current
// port
- if (!
l
ayer.tryTiming(src_port)) {
+ if (!
snoopRespL
ayer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@
-274,7
+284,7
@@
CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
assert(!pkt->isExpressSnoop());
calcPacketTiming(pkt);
assert(!pkt->isExpressSnoop());
calcPacketTiming(pkt);
- Tick packetFinishTime = pkt->
finishTime
;
+ Tick packetFinishTime = pkt->
busLastWordDelay + curTick()
;
// determine if the response is from a snoop request we
// created as the result of a normal request (in which case it
// determine if the response is from a snoop request we
// created as the result of a normal request (in which case it
@@
-309,7
+319,7
@@
CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
assert(success);
}
assert(success);
}
-
l
ayer.succeededTiming(packetFinishTime);
+
snoopRespL
ayer.succeededTiming(packetFinishTime);
return true;
}
return true;
}
@@
-318,6
+328,9
@@
CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
void
CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
{
void
CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
{
+ // snoops should only happen if the system isn't bypassing caches
+ assert(!system->bypassCaches());
+
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s;
// we could have gotten this request from a snooping master
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s;
// we could have gotten this request from a snooping master
@@
-335,8
+348,10
@@
CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
void
CoherentBus::recvRetry()
{
void
CoherentBus::recvRetry()
{
- // only one layer that can deal with it
- layer.recvRetry();
+ // responses and snoop responses never block on forwarding them,
+ // so the retry will always be coming from a port to which we
+ // tried to forward a request
+ reqLayer.recvRetry();
}
Tick
}
Tick
@@
-350,7
+365,7
@@
CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id)
Tick snoop_response_latency = 0;
// uncacheable requests need never be snooped
Tick snoop_response_latency = 0;
// uncacheable requests need never be snooped
- if (!pkt->req->isUncacheable()) {
+ if (!pkt->req->isUncacheable()
&& !system->bypassCaches()
) {
// forward to all snoopers but the source
std::pair<MemCmd, Tick> snoop_result =
forwardAtomic(pkt, slave_port_id);
// forward to all snoopers but the source
std::pair<MemCmd, Tick> snoop_result =
forwardAtomic(pkt, slave_port_id);
@@
-373,7
+388,8
@@
CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id)
response_latency = snoop_response_latency;
}
response_latency = snoop_response_latency;
}
- pkt->finishTime = curTick() + response_latency;
+ // @todo: Not setting first-word time
+ pkt->busLastWordDelay = response_latency;
return response_latency;
}
return response_latency;
}
@@
-393,7
+409,8
@@
CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id)
if (snoop_response_cmd != MemCmd::InvalidCmd)
pkt->cmd = snoop_response_cmd;
if (snoop_response_cmd != MemCmd::InvalidCmd)
pkt->cmd = snoop_response_cmd;
- pkt->finishTime = curTick() + snoop_response_latency;
+ // @todo: Not setting first-word time
+ pkt->busLastWordDelay = snoop_response_latency;
return snoop_response_latency;
}
return snoop_response_latency;
}
@@
-407,6
+424,9
@@
CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id)
MemCmd snoop_response_cmd = MemCmd::InvalidCmd;
Tick snoop_response_latency = 0;
MemCmd snoop_response_cmd = MemCmd::InvalidCmd;
Tick snoop_response_latency = 0;
+ // snoops should only happen if the system isn't bypassing caches
+ assert(!system->bypassCaches());
+
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s;
// we could have gotten this request from a snooping master
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s;
// we could have gotten this request from a snooping master
@@
-451,7
+471,7
@@
CoherentBus::recvFunctional(PacketPtr pkt, PortID slave_port_id)
}
// uncacheable requests need never be snooped
}
// uncacheable requests need never be snooped
- if (!pkt->req->isUncacheable()) {
+ if (!pkt->req->isUncacheable()
&& !system->bypassCaches()
) {
// forward to all snoopers but the source
forwardFunctional(pkt, slave_port_id);
}
// forward to all snoopers but the source
forwardFunctional(pkt, slave_port_id);
}
@@
-483,6
+503,9
@@
CoherentBus::recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id)
void
CoherentBus::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id)
{
void
CoherentBus::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id)
{
+ // snoops should only happen if the system isn't bypassing caches
+ assert(!system->bypassCaches());
+
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s;
// we could have gotten this request from a snooping master
for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
SlavePort *p = *s;
// we could have gotten this request from a snooping master
@@
-501,10
+524,10
@@
CoherentBus::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id)
}
unsigned int
}
unsigned int
-CoherentBus::drain(
Event *de
)
+CoherentBus::drain(
DrainManager *dm
)
{
{
- //
only one layer to worry about at the moment
- return
layer.drain(de
);
+ //
sum up the individual layers
+ return
reqLayer.drain(dm) + respLayer.drain(dm) + snoopRespLayer.drain(dm
);
}
CoherentBus *
}
CoherentBus *