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_impl.hh | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') 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/cache_impl.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mem/cache/cache_impl.hh') 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_impl.hh | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') 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/cache_impl.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') 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/cache_impl.hh') 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