diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/memtest/memtest.cc | 10 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/fetch.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 9 | ||||
-rw-r--r-- | src/cpu/o3/lsq.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/lsq_impl.hh | 10 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 12 | ||||
-rw-r--r-- | src/cpu/simple/atomic.hh | 2 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 11 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 4 | ||||
-rw-r--r-- | src/mem/bus.cc | 43 | ||||
-rw-r--r-- | src/mem/cache/base_cache.hh | 7 | ||||
-rw-r--r-- | src/mem/cache/miss/miss_queue.cc | 2 |
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); |