From 13ef7a56478fdd993a726833e14a85307446c28f Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:07 -0600 Subject: MEM: Differentiate functional cache accesses from CPU and memory This patch changes the functionalAccess member function in the cache model such that it is aware of what port the access came from, i.e. if it came from the CPU side or from the memory side. By adding this information, it is possible to respect the 'forwardSnoops' flag for snooping requests coming from the memory side and not forward them. This fixes an outstanding issue with the IO bus getting accesses that have no valid destination port and also cleans up future changes to the bus model. --- src/mem/cache/cache.hh | 17 ++++++++++++++--- src/mem/cache/cache_impl.hh | 24 +++++++++++++++--------- 2 files changed, 29 insertions(+), 12 deletions(-) (limited to 'src/mem/cache') diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 1ed138bb5..8d30ed443 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * @@ -225,10 +237,9 @@ class Cache : public BaseCache /** * Performs the access specified by the request. * @param pkt The request to perform. - * @return The result of the access. + * @param fromCpuSide from the CPU side port or the memory side port */ - void functionalAccess(PacketPtr pkt, CachePort *incomingPort, - CachePort *otherSidePort); + void functionalAccess(PacketPtr pkt, bool fromCpuSide); /** * Handles a response (cache line fill/write ack) from the bus. diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index a56495abb..453e62b1a 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010-2012 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -768,9 +768,7 @@ Cache::atomicAccess(PacketPtr pkt) template void -Cache::functionalAccess(PacketPtr pkt, - CachePort *incomingPort, - CachePort *otherSidePort) +Cache::functionalAccess(PacketPtr pkt, bool fromCpuSide) { Addr blk_addr = blockAlign(pkt->getAddr()); BlkType *blk = tags->findBlock(pkt->getAddr()); @@ -796,10 +794,10 @@ Cache::functionalAccess(PacketPtr pkt, (mshr && mshr->inService && mshr->isPendingDirty())); bool done = have_dirty - || incomingPort->checkFunctional(pkt) + || cpuSidePort->checkFunctional(pkt) || mshrQueue.checkFunctional(pkt, blk_addr) || writeBuffer.checkFunctional(pkt, blk_addr) - || otherSidePort->checkFunctional(pkt); + || memSidePort->checkFunctional(pkt); DPRINTF(Cache, "functional %s %x %s%s%s\n", pkt->cmdString(), pkt->getAddr(), @@ -812,7 +810,15 @@ Cache::functionalAccess(PacketPtr pkt, if (done) { pkt->makeResponse(); } else { - otherSidePort->sendFunctional(pkt); + // if it came as a request from the CPU side then make sure it + // continues towards the memory side + if (fromCpuSide) { + memSidePort->sendFunctional(pkt); + } else if (forwardSnoops) { + // if it came from the memory side, it must be a snoop request + // and we should only forward it if we are forwarding snoops + cpuSidePort->sendFunctional(pkt); + } } } @@ -1598,7 +1604,7 @@ template void Cache::CpuSidePort::recvFunctional(PacketPtr pkt) { - myCache()->functionalAccess(pkt, this, otherPort); + myCache()->functionalAccess(pkt, true); } @@ -1670,7 +1676,7 @@ template void Cache::MemSidePort::recvFunctional(PacketPtr pkt) { - myCache()->functionalAccess(pkt, this, otherPort); + myCache()->functionalAccess(pkt, false); } -- cgit v1.2.3 From de34e49d15b95cc8be51dbed2e98c469e7486959 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: MEM: Simplify ports by removing EventManager This patch removes the inheritance of EventManager from the ports and moves all responsibility for event queues to the owner. Eventually the event manager should be the interface block, which could either be the structural owner or a subblock like a LSQ in the O3 CPU for example. --- src/mem/cache/base.cc | 2 +- src/mem/cache/cache_impl.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mem/cache') diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 7863edde0..023b74323 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -126,7 +126,7 @@ BaseCache::CachePort::clearBlocked() mustSendRetry = false; SendRetryEvent *ev = new SendRetryEvent(this, true); // @TODO: need to find a better time (next bus cycle?) - schedule(ev, curTick() + 1); + cache->schedule(ev, curTick() + 1); } } diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 453e62b1a..581435010 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1729,7 +1729,7 @@ Cache::MemSidePort::sendPacket() // @TODO: need to facotr in prefetch requests here somehow if (nextReady != MaxTick) { DPRINTF(CachePort, "more packets to send @ %d\n", nextReady); - schedule(sendEvent, std::max(nextReady, curTick() + 1)); + cache->schedule(sendEvent, std::max(nextReady, curTick() + 1)); } else { // no more to send right now: if we're draining, we may be done if (drainEvent && !sendEvent->scheduled()) { -- cgit v1.2.3 From 142380a373e28cd61b79d348361ec1ed4ed330e5 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: MEM: Remove Port removeConn and MemObject deletePortRefs Cleaning up and simplifying the ports and going towards a more strict elaboration-time creation and binding of the ports. --- src/mem/cache/cache.hh | 1 - src/mem/cache/cache_impl.hh | 11 ----------- 2 files changed, 12 deletions(-) (limited to 'src/mem/cache') diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 8d30ed443..7b1c877f9 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -216,7 +216,6 @@ class Cache : public BaseCache Cache(const Params *p, TagStore *tags, BasePrefetcher *prefetcher); virtual Port *getPort(const std::string &if_name, int idx = -1); - virtual void deletePortRefs(Port *p); void regStats(); diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 581435010..1e5b59e17 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -114,17 +114,6 @@ Cache::getPort(const std::string &if_name, int idx) } } -template -void -Cache::deletePortRefs(Port *p) -{ - if (cpuSidePort == p || memSidePort == p) - panic("Can only delete functional ports\n"); - - delete p; -} - - template void Cache::cmpAndSwap(BlkType *blk, PacketPtr pkt) -- cgit v1.2.3 From 07cf9d914b292008ead7021182ec2ef8fc4671f1 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: MEM: Separate queries for snooping and address ranges This patch simplifies the address-range determination mechanism and also unifies the naming across ports and devices. It further splits the queries for determining if a port is snooping and what address ranges it responds to (aiming towards a separation of cache-maintenance ports and pure memory-mapped ports). Default behaviours are such that most ports do not have to define isSnooping, and master ports need not implement getAddrRanges. --- src/mem/cache/base.cc | 8 +++----- src/mem/cache/base.hh | 2 +- src/mem/cache/cache.hh | 6 ++---- src/mem/cache/cache_impl.hh | 16 ++++++++-------- 4 files changed, 14 insertions(+), 18 deletions(-) (limited to 'src/mem/cache') diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 023b74323..278329152 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -70,11 +70,9 @@ BaseCache::BaseCache(const Params *p) } void -BaseCache::CachePort::recvStatusChange(Port::Status status) +BaseCache::CachePort::recvRangeChange() const { - if (status == Port::RangeChange) { - otherPort->sendStatusChange(Port::RangeChange); - } + otherPort->sendRangeChange(); } @@ -136,7 +134,7 @@ BaseCache::init() { if (!cpuSidePort || !memSidePort) panic("Cache not hooked up on both sides\n"); - cpuSidePort->sendStatusChange(Port::RangeChange); + cpuSidePort->sendRangeChange(); } diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index 297692b32..e6a5c284f 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -105,7 +105,7 @@ class BaseCache : public MemObject CachePort(const std::string &_name, BaseCache *_cache, const std::string &_label); - virtual void recvStatusChange(Status status); + virtual void recvRangeChange() const; virtual unsigned deviceBlockSize() const; diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 7b1c877f9..b5c95b301 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -90,8 +90,7 @@ class Cache : public BaseCache return static_cast *>(cache); } - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual AddrRangeList getAddrRanges(); virtual bool recvTiming(PacketPtr pkt); @@ -118,8 +117,7 @@ class Cache : public BaseCache void processSendEvent(); - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual bool isSnooping(); virtual bool recvTiming(PacketPtr pkt); diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 1e5b59e17..46692a8d3 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1554,14 +1554,15 @@ Cache::nextMSHRReadyTime() /////////////// template -void +AddrRangeList Cache::CpuSidePort:: -getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) +getAddrRanges() { // 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()); + AddrRangeList ranges; + ranges.push_back(myCache()->getAddrRange()); + return ranges; } @@ -1612,14 +1613,13 @@ CpuSidePort::CpuSidePort(const std::string &_name, Cache *_cache, /////////////// template -void -Cache::MemSidePort:: -getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) +bool +Cache::MemSidePort::isSnooping() { // 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; + return true; } -- cgit v1.2.3 From e731cf4c1df8db0c7bcb689aba0146199a93b64e Mon Sep 17 00:00:00 2001 From: William Wang Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: MEM: Remove the functional ports from the memory system The functional ports are no longer used and this patch cleans up the legacy that is still present in buses, memories, CPUs etc. Note that this does not refer to the class FunctionalPort (already removed), but rather ports with the name (and use) functional. --- src/mem/cache/cache_impl.hh | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/mem/cache') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 46692a8d3..13484eb79 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -103,13 +103,7 @@ Cache::getPort(const std::string &if_name, int idx) return cpuSidePort; } else if (if_name == "mem_side") { return memSidePort; - } else if (if_name == "functional") { - CpuSidePort *funcPort = - new CpuSidePort(name() + "-cpu_side_funcport", this, - "CpuSideFuncPort"); - funcPort->setOtherPort(memSidePort); - return funcPort; - } else { + } else { panic("Port name %s unrecognized\n", if_name); } } -- cgit v1.2.3