summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cpu/memtest/memtest.cc10
-rw-r--r--src/cpu/memtest/memtest.hh4
-rw-r--r--src/cpu/o3/fetch.hh2
-rw-r--r--src/cpu/o3/fetch_impl.hh9
-rw-r--r--src/cpu/o3/lsq.hh2
-rw-r--r--src/cpu/o3/lsq_impl.hh10
-rw-r--r--src/cpu/simple/atomic.cc12
-rw-r--r--src/cpu/simple/atomic.hh2
-rw-r--r--src/cpu/simple/timing.cc11
-rw-r--r--src/cpu/simple/timing.hh4
-rw-r--r--src/mem/bus.cc43
-rw-r--r--src/mem/cache/base_cache.hh7
-rw-r--r--src/mem/cache/miss/miss_queue.cc2
13 files changed, 97 insertions, 21 deletions
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 91e073cf0..180f41541 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -81,8 +81,13 @@ MemTest::CpuPort::recvFunctional(PacketPtr pkt)
void
MemTest::CpuPort::recvStatusChange(Status status)
{
- if (status == RangeChange)
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
return;
+ }
panic("MemTest doesn't expect recvStatusChange callback!");
}
@@ -145,6 +150,9 @@ MemTest::MemTest(const string &name,
// thread = new SimpleThread(NULL, 0, NULL, 0, mainMem);
curTick = 0;
+ cachePort.snoopRangeSent = false;
+ funcPort.snoopRangeSent = true;
+
// Needs to be masked off once we know the block size.
traceBlockAddr = _traceAddr;
baseAddr1 = 0x100000;
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
index 2694efd39..7bf34d827 100644
--- a/src/cpu/memtest/memtest.hh
+++ b/src/cpu/memtest/memtest.hh
@@ -100,6 +100,8 @@ class MemTest : public MemObject
: Port(_name, _memtest), memtest(_memtest)
{ }
+ bool snoopRangeSent;
+
protected:
virtual bool recvTiming(PacketPtr pkt);
@@ -120,6 +122,8 @@ class MemTest : public MemObject
CpuPort cachePort;
CpuPort funcPort;
+ bool snoopRangeSent;
+
class MemTestSenderState : public Packet::SenderState
{
public:
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index cc9a8abf5..04016347a 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -83,6 +83,8 @@ class DefaultFetch
: Port(_fetch->name() + "-iport"), fetch(_fetch)
{ }
+ bool snoopRangeSent;
+
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 25faa407e..63d22b293 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -70,8 +70,13 @@ template<class Impl>
void
DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status)
{
- if (status == RangeChange)
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
return;
+ }
panic("DefaultFetch doesn't expect recvStatusChange callback!");
}
@@ -287,6 +292,8 @@ DefaultFetch<Impl>::setCPU(O3CPU *cpu_ptr)
// Name is finally available, so create the port.
icachePort = new IcachePort(this);
+ icachePort->snoopRangeSent = false;
+
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setIcachePort(icachePort);
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index 6b12d75b4..7559a36d5 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -298,6 +298,8 @@ class LSQ {
: lsq(_lsq)
{ }
+ bool snoopRangeSent;
+
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 5e7945c1c..6758e51c8 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -53,9 +53,13 @@ template <class Impl>
void
LSQ<Impl>::DcachePort::recvStatusChange(Status status)
{
- if (status == RangeChange)
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
return;
-
+ }
panic("O3CPU doesn't expect recvStatusChange callback!");
}
@@ -97,6 +101,8 @@ LSQ<Impl>::LSQ(Params *params)
{
DPRINTF(LSQ, "Creating LSQ object.\n");
+ dcachePort.snoopRangeSent = false;
+
//**********************************************/
//************ Handle SMT Parameters ***********/
//**********************************************/
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 58dc1fe5f..325260609 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -94,7 +94,7 @@ Tick
AtomicSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
{
//Snooping a coherence request, just return
- return curTick;
+ return 0;
}
void
@@ -107,8 +107,13 @@ AtomicSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
void
AtomicSimpleCPU::CpuPort::recvStatusChange(Status status)
{
- if (status == RangeChange)
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
return;
+ }
panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!");
}
@@ -127,6 +132,9 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
{
_status = Idle;
+ icachePort.snoopRangeSent = false;
+ dcachePort.snoopRangeSent = false;
+
ifetch_req = new Request();
ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 166a18127..0df6fe079 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -90,6 +90,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
: Port(_name, _cpu), cpu(_cpu)
{ }
+ bool snoopRangeSent;
+
protected:
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index db2c940c0..1ea2df894 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -82,8 +82,13 @@ TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
void
TimingSimpleCPU::CpuPort::recvStatusChange(Status status)
{
- if (status == RangeChange)
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
return;
+ }
panic("TimingSimpleCPU doesn't expect recvStatusChange callback!");
}
@@ -101,6 +106,10 @@ TimingSimpleCPU::TimingSimpleCPU(Params *p)
cpu_id(p->cpu_id)
{
_status = Idle;
+
+ icachePort.snoopRangeSent = false;
+ dcachePort.snoopRangeSent = false;
+
ifetch_pkt = dcache_pkt = NULL;
drainEvent = NULL;
fetchEvent = NULL;
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 408fa315e..fe5d03666 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -82,6 +82,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
: Port(_name, _cpu), cpu(_cpu), lat(_lat)
{ }
+ bool snoopRangeSent;
+
protected:
virtual Tick recvAtomic(PacketPtr pkt);
@@ -166,8 +168,6 @@ class TimingSimpleCPU : public BaseSimpleCPU
PacketPtr ifetch_pkt;
PacketPtr dcache_pkt;
-
-
int cpu_id;
Tick previousTick;
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 8ea67a0e4..b97a7ddb9 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -290,7 +290,10 @@ Bus::findPort(Addr addr, int id)
// we shouldn't be sending this back to where it came from
- assert(dest_id != id);
+ // only on a functional access and then we should terminate
+ // the cyclical call.
+ if (dest_id == id)
+ return 0;
return interfaces[dest_id];
}
@@ -307,7 +310,18 @@ Bus::findSnoopPorts(Addr addr, int id)
if (portSnoopList[i].range == addr && portSnoopList[i].portId != id) {
//Careful to not overlap ranges
//or snoop will be called more than once on the port
- ports.push_back(portSnoopList[i].portId);
+
+ //@todo Fix this hack because ranges are overlapping
+ //need to make sure we dont't create overlapping ranges
+ bool hack_overlap = false;
+ int size = ports.size();
+ for (int j=0; j < size; j++) {
+ if (ports[j] == portSnoopList[i].portId)
+ hack_overlap = true;
+ }
+
+ if (!hack_overlap)
+ ports.push_back(portSnoopList[i].portId);
// DPRINTF(Bus, " found snoop addr %#llx on device%d\n", addr,
// portSnoopList[i].portId);
}
@@ -339,10 +353,13 @@ Bus::functionalSnoop(PacketPtr pkt)
{
std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc());
+ //The packet may be changed by another bus on snoops, restore the id after each
+ int id = pkt->getSrc();
while (!ports.empty() && pkt->result != Packet::Success)
{
interfaces[ports.back()]->sendFunctional(pkt);
ports.pop_back();
+ pkt->setSrc(id);
}
}
@@ -392,8 +409,11 @@ Bus::recvFunctional(PacketPtr pkt)
functionalSnoop(pkt);
// If the snooping found what we were looking for, we're done.
- if (pkt->result != Packet::Success)
- findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt);
+ if (pkt->result != Packet::Success) {
+ Port* port = findPort(pkt->getAddr(), pkt->getSrc());
+ if (port)
+ port->sendFunctional(pkt);
+ }
}
/** Function called by the port when the bus is receiving a status change.*/
@@ -451,6 +471,7 @@ Bus::recvStatusChange(Port::Status status, int id)
dm.portId = id;
dm.range = *iter;
+ //@todo, make sure we don't overlap ranges
DPRINTF(BusAddrRanges, "Adding snoop range %#llx - %#llx for id %d\n",
dm.range.start, dm.range.end, id);
portSnoopList.push_back(dm);
@@ -493,7 +514,7 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end();
dflt_iter++) {
resp.push_back(*dflt_iter);
- DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n",dflt_iter->start,
+ DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start,
dflt_iter->end);
}
for (portIter = portList.begin(); portIter != portList.end(); portIter++) {
@@ -519,6 +540,18 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
portIter->range.start, portIter->range.end);
}
}
+
+ for (portIter = portSnoopList.begin();
+ portIter != portSnoopList.end(); portIter++)
+ {
+ if (portIter->portId != id) {
+ snoop.push_back(portIter->range);
+ DPRINTF(BusAddrRanges, " -- Snoop: %#llx : %#llx\n",
+ portIter->range.start, portIter->range.end);
+ //@todo We need to properly insert snoop ranges
+ //not overlapping the ranges (multiple)
+ }
+ }
}
unsigned int
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index 584c2d5df..ef4955432 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -144,8 +144,6 @@ class BaseCache : public MemObject
protected:
CachePort *memSidePort;
- bool snoopRangesSent;
-
public:
virtual Port *getPort(const std::string &if_name, int idx = -1);
@@ -171,10 +169,6 @@ class BaseCache : public MemObject
if (status == Port::RangeChange){
if (!isCpuSide) {
cpuSidePort->sendStatusChange(Port::RangeChange);
- if (!snoopRangesSent) {
- snoopRangesSent = true;
- memSidePort->sendStatusChange(Port::RangeChange);
- }
}
else {
memSidePort->sendStatusChange(Port::RangeChange);
@@ -358,7 +352,6 @@ class BaseCache : public MemObject
//Start ports at null if more than one is created we should panic
cpuSidePort = NULL;
memSidePort = NULL;
- snoopRangesSent = false;
}
~BaseCache()
diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc
index fe467a8ea..3c4586272 100644
--- a/src/mem/cache/miss/miss_queue.cc
+++ b/src/mem/cache/miss/miss_queue.cc
@@ -612,6 +612,8 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
if (mshr->hasTargets()) {
// Didn't satisfy all the targets, need to resend
Packet::Command cmd = mshr->getTarget()->cmd;
+ mshr->pkt->setDest(Packet::Broadcast);
+ mshr->pkt->result = Packet::Unknown;
mq.markPending(mshr, cmd);
mshr->order = order++;
cache->setMasterRequest(Request_MSHR, time);