diff options
author | Steve Reinhardt <Steve.Reinhardt@amd.com> | 2008-07-16 11:10:33 -0700 |
---|---|---|
committer | Steve Reinhardt <Steve.Reinhardt@amd.com> | 2008-07-16 11:10:33 -0700 |
commit | 6629d9b2bc58a885bfebce1517fd12483497b6e4 (patch) | |
tree | 22e2bc30405ba483ac571951f49cc77d7e713477 /src/mem/cache/cache_impl.hh | |
parent | 05d8c9acb8a5a985956998fc13551288496e5cdc (diff) | |
download | gem5-6629d9b2bc58a885bfebce1517fd12483497b6e4.tar.xz |
mem: use single BadAddr responder per system.
Previously there was one per bus, which caused some coherence problems
when more than one decided to respond. Now there is just one on
the main memory bus. The default bus responder on all other buses
is now the downstream cache's cpu_side port. Caches no longer need
to do address range filtering; instead, we just have a simple flag
to prevent snoops from propagating to the I/O bus.
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r-- | src/mem/cache/cache_impl.hh | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index ea8ae0046..82db7750c 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -40,7 +40,7 @@ #include "sim/host.hh" #include "base/fast_alloc.hh" #include "base/misc.hh" -#include "base/range_ops.hh" +#include "base/range.hh" #include "mem/cache/cache.hh" #include "mem/cache/blk.hh" @@ -62,11 +62,9 @@ Cache<TagStore>::Cache(const Params *p, TagStore *tags, BasePrefetcher *pf) tempBlock->data = new uint8_t[blkSize]; cpuSidePort = new CpuSidePort(p->name + "-cpu_side_port", this, - "CpuSidePort", - p->cpu_side_filter_ranges); + "CpuSidePort"); memSidePort = new MemSidePort(p->name + "-mem_side_port", this, - "MemSidePort", - p->mem_side_filter_ranges); + "MemSidePort"); cpuSidePort->setOtherPort(memSidePort); memSidePort->setOtherPort(cpuSidePort); @@ -96,8 +94,7 @@ Cache<TagStore>::getPort(const std::string &if_name, int idx) } else if (if_name == "functional") { CpuSidePort *funcPort = new CpuSidePort(name() + "-cpu_side_funcport", this, - "CpuSideFuncPort", - std::vector<Range<Addr> >()); + "CpuSideFuncPort"); funcPort->setOtherPort(memSidePort); return funcPort; } else { @@ -1063,35 +1060,37 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk, assert(!(pending_inval && !is_deferred)); assert(pkt->isRequest()); - // first propagate snoop upward to see if anyone above us wants to - // handle it. save & restore packet src since it will get - // rewritten to be relative to cpu-side bus (if any) - bool alreadyResponded = pkt->memInhibitAsserted(); - if (is_timing) { - Packet *snoopPkt = new Packet(pkt, true); // clear flags - snoopPkt->setExpressSnoop(); - snoopPkt->senderState = new ForwardResponseRecord(pkt, this); - cpuSidePort->sendTiming(snoopPkt); - if (snoopPkt->memInhibitAsserted()) { - // cache-to-cache response from some upper cache - assert(!alreadyResponded); - pkt->assertMemInhibit(); + if (forwardSnoops) { + // first propagate snoop upward to see if anyone above us wants to + // handle it. save & restore packet src since it will get + // rewritten to be relative to cpu-side bus (if any) + bool alreadyResponded = pkt->memInhibitAsserted(); + if (is_timing) { + Packet *snoopPkt = new Packet(pkt, true); // clear flags + snoopPkt->setExpressSnoop(); + snoopPkt->senderState = new ForwardResponseRecord(pkt, this); + cpuSidePort->sendTiming(snoopPkt); + if (snoopPkt->memInhibitAsserted()) { + // cache-to-cache response from some upper cache + assert(!alreadyResponded); + pkt->assertMemInhibit(); + } else { + delete snoopPkt->senderState; + } + if (snoopPkt->sharedAsserted()) { + pkt->assertShared(); + } + delete snoopPkt; } else { - delete snoopPkt->senderState; - } - if (snoopPkt->sharedAsserted()) { - pkt->assertShared(); - } - delete snoopPkt; - } else { - int origSrc = pkt->getSrc(); - cpuSidePort->sendAtomic(pkt); - if (!alreadyResponded && pkt->memInhibitAsserted()) { - // cache-to-cache response from some upper cache: - // forward response to original requester - assert(pkt->isResponse()); + int origSrc = pkt->getSrc(); + cpuSidePort->sendAtomic(pkt); + if (!alreadyResponded && pkt->memInhibitAsserted()) { + // cache-to-cache response from some upper cache: + // forward response to original requester + assert(pkt->isResponse()); + } + pkt->setSrc(origSrc); } - pkt->setSrc(origSrc); } if (!blk || !blk->isValid()) { @@ -1385,11 +1384,10 @@ void Cache<TagStore>::CpuSidePort:: getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) { - // CPU side port doesn't snoop; it's a target only. - bool dummy; - otherPort->getPeerAddressRanges(resp, dummy); - FilterRangeList(filterRanges, resp); + // CPU side port doesn't snoop; it's a target only. It can + // potentially respond to any address. snoop = false; + resp.push_back(myCache()->getAddrRange()); } @@ -1428,9 +1426,8 @@ Cache<TagStore>::CpuSidePort::recvFunctional(PacketPtr pkt) template<class TagStore> Cache<TagStore>:: CpuSidePort::CpuSidePort(const std::string &_name, Cache<TagStore> *_cache, - const std::string &_label, - std::vector<Range<Addr> > filterRanges) - : BaseCache::CachePort(_name, _cache, _label, filterRanges) + const std::string &_label) + : BaseCache::CachePort(_name, _cache, _label) { } @@ -1445,11 +1442,9 @@ void Cache<TagStore>::MemSidePort:: getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) { - otherPort->getPeerAddressRanges(resp, snoop); - FilterRangeList(filterRanges, resp); - - // Memory-side port always snoops, so unconditionally set flag for - // caller. + // Memory-side port always snoops, but never passes requests + // through to targets on the cpu side (so we don't add anything to + // the address range list). snoop = true; } @@ -1581,9 +1576,8 @@ Cache<TagStore>::MemSidePort::processSendEvent() template<class TagStore> Cache<TagStore>:: MemSidePort::MemSidePort(const std::string &_name, Cache<TagStore> *_cache, - const std::string &_label, - std::vector<Range<Addr> > filterRanges) - : BaseCache::CachePort(_name, _cache, _label, filterRanges) + const std::string &_label) + : BaseCache::CachePort(_name, _cache, _label) { // override default send event from SimpleTimingPort delete sendEvent; |