112726Snikos.nikoleris@arm.com/* 212726Snikos.nikoleris@arm.com * Copyright (c) 2010-2018 ARM Limited 312726Snikos.nikoleris@arm.com * All rights reserved. 412726Snikos.nikoleris@arm.com * 512726Snikos.nikoleris@arm.com * The license below extends only to copyright in the software and shall 612726Snikos.nikoleris@arm.com * not be construed as granting a license to any other intellectual 712726Snikos.nikoleris@arm.com * property including but not limited to intellectual property relating 812726Snikos.nikoleris@arm.com * to a hardware implementation of the functionality of the software 912726Snikos.nikoleris@arm.com * licensed hereunder. You may use the software subject to the license 1012726Snikos.nikoleris@arm.com * terms below provided that you ensure that this notice is replicated 1112726Snikos.nikoleris@arm.com * unmodified and in its entirety in all distributions of the software, 1212726Snikos.nikoleris@arm.com * modified or unmodified, in source code or in binary form. 1312726Snikos.nikoleris@arm.com * 1412726Snikos.nikoleris@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 1512726Snikos.nikoleris@arm.com * Copyright (c) 2010,2015 Advanced Micro Devices, Inc. 1612726Snikos.nikoleris@arm.com * All rights reserved. 1712726Snikos.nikoleris@arm.com * 1812726Snikos.nikoleris@arm.com * Redistribution and use in source and binary forms, with or without 1912726Snikos.nikoleris@arm.com * modification, are permitted provided that the following conditions are 2012726Snikos.nikoleris@arm.com * met: redistributions of source code must retain the above copyright 2112726Snikos.nikoleris@arm.com * notice, this list of conditions and the following disclaimer; 2212726Snikos.nikoleris@arm.com * redistributions in binary form must reproduce the above copyright 2312726Snikos.nikoleris@arm.com * notice, this list of conditions and the following disclaimer in the 2412726Snikos.nikoleris@arm.com * documentation and/or other materials provided with the distribution; 2512726Snikos.nikoleris@arm.com * neither the name of the copyright holders nor the names of its 2612726Snikos.nikoleris@arm.com * contributors may be used to endorse or promote products derived from 2712726Snikos.nikoleris@arm.com * this software without specific prior written permission. 2812726Snikos.nikoleris@arm.com * 2912726Snikos.nikoleris@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3012726Snikos.nikoleris@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3112726Snikos.nikoleris@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3212726Snikos.nikoleris@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3312726Snikos.nikoleris@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3412726Snikos.nikoleris@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3512726Snikos.nikoleris@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3612726Snikos.nikoleris@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3712726Snikos.nikoleris@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3812726Snikos.nikoleris@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3912726Snikos.nikoleris@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4012726Snikos.nikoleris@arm.com * 4112726Snikos.nikoleris@arm.com * Authors: Erik Hallnor 4212726Snikos.nikoleris@arm.com * Dave Greene 4312726Snikos.nikoleris@arm.com * Nathan Binkert 4412726Snikos.nikoleris@arm.com * Steve Reinhardt 4512726Snikos.nikoleris@arm.com * Ron Dreslinski 4612726Snikos.nikoleris@arm.com * Andreas Sandberg 4712726Snikos.nikoleris@arm.com * Nikos Nikoleris 4812726Snikos.nikoleris@arm.com */ 4912726Snikos.nikoleris@arm.com 5012726Snikos.nikoleris@arm.com/** 5112726Snikos.nikoleris@arm.com * @file 5212726Snikos.nikoleris@arm.com * Cache definitions. 5312726Snikos.nikoleris@arm.com */ 5412726Snikos.nikoleris@arm.com 5512726Snikos.nikoleris@arm.com#include "mem/cache/noncoherent_cache.hh" 5612726Snikos.nikoleris@arm.com 5712726Snikos.nikoleris@arm.com#include <cassert> 5812726Snikos.nikoleris@arm.com 5912726Snikos.nikoleris@arm.com#include "base/logging.hh" 6012726Snikos.nikoleris@arm.com#include "base/trace.hh" 6112726Snikos.nikoleris@arm.com#include "base/types.hh" 6212726Snikos.nikoleris@arm.com#include "debug/Cache.hh" 6313223Sodanrc@yahoo.com.br#include "mem/cache/cache_blk.hh" 6412726Snikos.nikoleris@arm.com#include "mem/cache/mshr.hh" 6512726Snikos.nikoleris@arm.com#include "params/NoncoherentCache.hh" 6612726Snikos.nikoleris@arm.com 6712726Snikos.nikoleris@arm.comNoncoherentCache::NoncoherentCache(const NoncoherentCacheParams *p) 6812726Snikos.nikoleris@arm.com : BaseCache(p, p->system->cacheLineSize()) 6912726Snikos.nikoleris@arm.com{ 7012726Snikos.nikoleris@arm.com} 7112726Snikos.nikoleris@arm.com 7212726Snikos.nikoleris@arm.comvoid 7312726Snikos.nikoleris@arm.comNoncoherentCache::satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool, bool) 7412726Snikos.nikoleris@arm.com{ 7512726Snikos.nikoleris@arm.com // As this a non-coherent cache located below the point of 7612726Snikos.nikoleris@arm.com // coherency, we do not expect requests that are typically used to 7712726Snikos.nikoleris@arm.com // keep caches coherent (e.g., InvalidateReq or UpdateReq). 7812726Snikos.nikoleris@arm.com assert(pkt->isRead() || pkt->isWrite()); 7912726Snikos.nikoleris@arm.com BaseCache::satisfyRequest(pkt, blk); 8012726Snikos.nikoleris@arm.com} 8112726Snikos.nikoleris@arm.com 8212726Snikos.nikoleris@arm.combool 8314035Sodanrc@yahoo.com.brNoncoherentCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, 8414035Sodanrc@yahoo.com.br PacketList &writebacks) 8512726Snikos.nikoleris@arm.com{ 8614035Sodanrc@yahoo.com.br bool success = BaseCache::access(pkt, blk, lat, writebacks); 8712726Snikos.nikoleris@arm.com 8812726Snikos.nikoleris@arm.com if (pkt->isWriteback() || pkt->cmd == MemCmd::WriteClean) { 8912726Snikos.nikoleris@arm.com assert(blk && blk->isValid()); 9012726Snikos.nikoleris@arm.com // Writeback and WriteClean can allocate and fill even if the 9112726Snikos.nikoleris@arm.com // referenced block was not present or it was invalid. If that 9212726Snikos.nikoleris@arm.com // is the case, make sure that the new block is marked as 9312726Snikos.nikoleris@arm.com // writable 9412726Snikos.nikoleris@arm.com blk->status |= BlkWritable; 9512726Snikos.nikoleris@arm.com } 9612726Snikos.nikoleris@arm.com 9712726Snikos.nikoleris@arm.com return success; 9812726Snikos.nikoleris@arm.com} 9912726Snikos.nikoleris@arm.com 10012726Snikos.nikoleris@arm.comvoid 10114035Sodanrc@yahoo.com.brNoncoherentCache::doWritebacks(PacketList& writebacks, Tick forward_time) 10212726Snikos.nikoleris@arm.com{ 10314035Sodanrc@yahoo.com.br while (!writebacks.empty()) { 10414035Sodanrc@yahoo.com.br PacketPtr wb_pkt = writebacks.front(); 10514035Sodanrc@yahoo.com.br allocateWriteBuffer(wb_pkt, forward_time); 10614035Sodanrc@yahoo.com.br writebacks.pop_front(); 10714035Sodanrc@yahoo.com.br } 10812726Snikos.nikoleris@arm.com} 10912726Snikos.nikoleris@arm.com 11012726Snikos.nikoleris@arm.comvoid 11114035Sodanrc@yahoo.com.brNoncoherentCache::doWritebacksAtomic(PacketList& writebacks) 11212726Snikos.nikoleris@arm.com{ 11314035Sodanrc@yahoo.com.br while (!writebacks.empty()) { 11414035Sodanrc@yahoo.com.br PacketPtr wb_pkt = writebacks.front(); 11514035Sodanrc@yahoo.com.br memSidePort.sendAtomic(wb_pkt); 11614035Sodanrc@yahoo.com.br writebacks.pop_front(); 11714035Sodanrc@yahoo.com.br delete wb_pkt; 11814035Sodanrc@yahoo.com.br } 11912726Snikos.nikoleris@arm.com} 12012726Snikos.nikoleris@arm.com 12112726Snikos.nikoleris@arm.comvoid 12212726Snikos.nikoleris@arm.comNoncoherentCache::handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, 12312726Snikos.nikoleris@arm.com Tick forward_time, Tick request_time) 12412726Snikos.nikoleris@arm.com{ 12512726Snikos.nikoleris@arm.com // miss 12612726Snikos.nikoleris@arm.com Addr blk_addr = pkt->getBlockAddr(blkSize); 12712726Snikos.nikoleris@arm.com MSHR *mshr = mshrQueue.findMatch(blk_addr, pkt->isSecure(), false); 12812726Snikos.nikoleris@arm.com 12912726Snikos.nikoleris@arm.com // We can always write to a non coherent cache if the block is 13012726Snikos.nikoleris@arm.com // present and therefore if we have reached this point then the 13112726Snikos.nikoleris@arm.com // block should not be in the cache. 13212726Snikos.nikoleris@arm.com assert(mshr || !blk || !blk->isValid()); 13312726Snikos.nikoleris@arm.com 13412726Snikos.nikoleris@arm.com BaseCache::handleTimingReqMiss(pkt, mshr, blk, forward_time, request_time); 13512726Snikos.nikoleris@arm.com} 13612726Snikos.nikoleris@arm.com 13712726Snikos.nikoleris@arm.comvoid 13812726Snikos.nikoleris@arm.comNoncoherentCache::recvTimingReq(PacketPtr pkt) 13912726Snikos.nikoleris@arm.com{ 14012726Snikos.nikoleris@arm.com panic_if(pkt->cacheResponding(), "Should not see packets where cache " 14112726Snikos.nikoleris@arm.com "is responding"); 14212726Snikos.nikoleris@arm.com 14312726Snikos.nikoleris@arm.com panic_if(!(pkt->isRead() || pkt->isWrite()), 14412726Snikos.nikoleris@arm.com "Should only see read and writes at non-coherent cache\n"); 14512726Snikos.nikoleris@arm.com 14612726Snikos.nikoleris@arm.com BaseCache::recvTimingReq(pkt); 14712726Snikos.nikoleris@arm.com} 14812726Snikos.nikoleris@arm.com 14912726Snikos.nikoleris@arm.comPacketPtr 15012726Snikos.nikoleris@arm.comNoncoherentCache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, 15113350Snikos.nikoleris@arm.com bool needs_writable, 15213350Snikos.nikoleris@arm.com bool is_whole_line_write) const 15312726Snikos.nikoleris@arm.com{ 15412726Snikos.nikoleris@arm.com // We also fill for writebacks from the coherent caches above us, 15512726Snikos.nikoleris@arm.com // and they do not need responses 15612726Snikos.nikoleris@arm.com assert(cpu_pkt->needsResponse()); 15712726Snikos.nikoleris@arm.com 15812726Snikos.nikoleris@arm.com // A miss can happen only due to missing block 15912726Snikos.nikoleris@arm.com assert(!blk || !blk->isValid()); 16012726Snikos.nikoleris@arm.com 16112726Snikos.nikoleris@arm.com PacketPtr pkt = new Packet(cpu_pkt->req, MemCmd::ReadReq, blkSize); 16212726Snikos.nikoleris@arm.com 16312726Snikos.nikoleris@arm.com // the packet should be block aligned 16412726Snikos.nikoleris@arm.com assert(pkt->getAddr() == pkt->getBlockAddr(blkSize)); 16512726Snikos.nikoleris@arm.com 16612726Snikos.nikoleris@arm.com pkt->allocate(); 16712726Snikos.nikoleris@arm.com DPRINTF(Cache, "%s created %s from %s\n", __func__, pkt->print(), 16812726Snikos.nikoleris@arm.com cpu_pkt->print()); 16912726Snikos.nikoleris@arm.com return pkt; 17012726Snikos.nikoleris@arm.com} 17112726Snikos.nikoleris@arm.com 17212726Snikos.nikoleris@arm.com 17312726Snikos.nikoleris@arm.comCycles 17414035Sodanrc@yahoo.com.brNoncoherentCache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk, 17514035Sodanrc@yahoo.com.br PacketList &writebacks) 17612726Snikos.nikoleris@arm.com{ 17713350Snikos.nikoleris@arm.com PacketPtr bus_pkt = createMissPacket(pkt, blk, true, 17813350Snikos.nikoleris@arm.com pkt->isWholeLineWrite(blkSize)); 17912726Snikos.nikoleris@arm.com DPRINTF(Cache, "Sending an atomic %s\n", bus_pkt->print()); 18012726Snikos.nikoleris@arm.com 18112726Snikos.nikoleris@arm.com Cycles latency = ticksToCycles(memSidePort.sendAtomic(bus_pkt)); 18212726Snikos.nikoleris@arm.com 18312726Snikos.nikoleris@arm.com assert(bus_pkt->isResponse()); 18412726Snikos.nikoleris@arm.com // At the moment the only supported downstream requests we issue 18512726Snikos.nikoleris@arm.com // are ReadReq and therefore here we should only see the 18612726Snikos.nikoleris@arm.com // corresponding responses 18712726Snikos.nikoleris@arm.com assert(bus_pkt->isRead()); 18812726Snikos.nikoleris@arm.com assert(pkt->cmd != MemCmd::UpgradeResp); 18912726Snikos.nikoleris@arm.com assert(!bus_pkt->isInvalidate()); 19012726Snikos.nikoleris@arm.com assert(!bus_pkt->hasSharers()); 19112726Snikos.nikoleris@arm.com 19212726Snikos.nikoleris@arm.com // We are now dealing with the response handling 19312726Snikos.nikoleris@arm.com DPRINTF(Cache, "Receive response: %s\n", bus_pkt->print()); 19412726Snikos.nikoleris@arm.com 19512726Snikos.nikoleris@arm.com if (!bus_pkt->isError()) { 19612726Snikos.nikoleris@arm.com // Any reponse that does not have an error should be filling, 19712726Snikos.nikoleris@arm.com // afterall it is a read response 19812726Snikos.nikoleris@arm.com DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n", 19912726Snikos.nikoleris@arm.com bus_pkt->getAddr()); 20014035Sodanrc@yahoo.com.br blk = handleFill(bus_pkt, blk, writebacks, allocOnFill(bus_pkt->cmd)); 20112726Snikos.nikoleris@arm.com assert(blk); 20212726Snikos.nikoleris@arm.com } 20312726Snikos.nikoleris@arm.com satisfyRequest(pkt, blk); 20412726Snikos.nikoleris@arm.com 20512726Snikos.nikoleris@arm.com maintainClusivity(true, blk); 20612726Snikos.nikoleris@arm.com 20712726Snikos.nikoleris@arm.com // Use the separate bus_pkt to generate response to pkt and 20812726Snikos.nikoleris@arm.com // then delete it. 20912726Snikos.nikoleris@arm.com if (!pkt->isWriteback() && pkt->cmd != MemCmd::WriteClean) { 21012726Snikos.nikoleris@arm.com assert(pkt->needsResponse()); 21112726Snikos.nikoleris@arm.com pkt->makeAtomicResponse(); 21212726Snikos.nikoleris@arm.com if (bus_pkt->isError()) { 21312726Snikos.nikoleris@arm.com pkt->copyError(bus_pkt); 21412726Snikos.nikoleris@arm.com } 21512726Snikos.nikoleris@arm.com } 21612726Snikos.nikoleris@arm.com 21712726Snikos.nikoleris@arm.com delete bus_pkt; 21812726Snikos.nikoleris@arm.com 21912726Snikos.nikoleris@arm.com return latency; 22012726Snikos.nikoleris@arm.com} 22112726Snikos.nikoleris@arm.com 22212726Snikos.nikoleris@arm.comTick 22312726Snikos.nikoleris@arm.comNoncoherentCache::recvAtomic(PacketPtr pkt) 22412726Snikos.nikoleris@arm.com{ 22512726Snikos.nikoleris@arm.com panic_if(pkt->cacheResponding(), "Should not see packets where cache " 22612726Snikos.nikoleris@arm.com "is responding"); 22712726Snikos.nikoleris@arm.com 22812726Snikos.nikoleris@arm.com panic_if(!(pkt->isRead() || pkt->isWrite()), 22912726Snikos.nikoleris@arm.com "Should only see read and writes at non-coherent cache\n"); 23012726Snikos.nikoleris@arm.com 23112726Snikos.nikoleris@arm.com return BaseCache::recvAtomic(pkt); 23212726Snikos.nikoleris@arm.com} 23312726Snikos.nikoleris@arm.com 23412726Snikos.nikoleris@arm.com 23512726Snikos.nikoleris@arm.comvoid 23612726Snikos.nikoleris@arm.comNoncoherentCache::functionalAccess(PacketPtr pkt, bool from_cpu_side) 23712726Snikos.nikoleris@arm.com{ 23812726Snikos.nikoleris@arm.com panic_if(!from_cpu_side, "Non-coherent cache received functional snoop" 23912726Snikos.nikoleris@arm.com " request\n"); 24012726Snikos.nikoleris@arm.com 24112726Snikos.nikoleris@arm.com BaseCache::functionalAccess(pkt, from_cpu_side); 24212726Snikos.nikoleris@arm.com} 24312726Snikos.nikoleris@arm.com 24412726Snikos.nikoleris@arm.comvoid 24512726Snikos.nikoleris@arm.comNoncoherentCache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, 24613478Sodanrc@yahoo.com.br CacheBlk *blk) 24712726Snikos.nikoleris@arm.com{ 24812726Snikos.nikoleris@arm.com // First offset for critical word first calculations 24913859Sodanrc@yahoo.com.br const int initial_offset = mshr->getTarget()->pkt->getOffset(blkSize); 25012726Snikos.nikoleris@arm.com 25112726Snikos.nikoleris@arm.com MSHR::TargetList targets = mshr->extractServiceableTargets(pkt); 25212726Snikos.nikoleris@arm.com for (auto &target: targets) { 25312726Snikos.nikoleris@arm.com Packet *tgt_pkt = target.pkt; 25412726Snikos.nikoleris@arm.com 25512726Snikos.nikoleris@arm.com switch (target.source) { 25612726Snikos.nikoleris@arm.com case MSHR::Target::FromCPU: 25712726Snikos.nikoleris@arm.com // handle deferred requests comming from a cache or core 25812726Snikos.nikoleris@arm.com // above 25912726Snikos.nikoleris@arm.com 26012726Snikos.nikoleris@arm.com Tick completion_time; 26112726Snikos.nikoleris@arm.com // Here we charge on completion_time the delay of the xbar if the 26212726Snikos.nikoleris@arm.com // packet comes from it, charged on headerDelay. 26312726Snikos.nikoleris@arm.com completion_time = pkt->headerDelay; 26412726Snikos.nikoleris@arm.com 26512726Snikos.nikoleris@arm.com satisfyRequest(tgt_pkt, blk); 26612726Snikos.nikoleris@arm.com 26712726Snikos.nikoleris@arm.com // How many bytes past the first request is this one 26812726Snikos.nikoleris@arm.com int transfer_offset; 26912726Snikos.nikoleris@arm.com transfer_offset = tgt_pkt->getOffset(blkSize) - initial_offset; 27012726Snikos.nikoleris@arm.com if (transfer_offset < 0) { 27112726Snikos.nikoleris@arm.com transfer_offset += blkSize; 27212726Snikos.nikoleris@arm.com } 27312726Snikos.nikoleris@arm.com // If not critical word (offset) return payloadDelay. 27412726Snikos.nikoleris@arm.com // responseLatency is the latency of the return path 27512726Snikos.nikoleris@arm.com // from lower level caches/memory to an upper level cache or 27612726Snikos.nikoleris@arm.com // the core. 27712726Snikos.nikoleris@arm.com completion_time += clockEdge(responseLatency) + 27812726Snikos.nikoleris@arm.com (transfer_offset ? pkt->payloadDelay : 0); 27912726Snikos.nikoleris@arm.com 28012726Snikos.nikoleris@arm.com assert(tgt_pkt->req->masterId() < system->maxMasters()); 28112726Snikos.nikoleris@arm.com missLatency[tgt_pkt->cmdToIndex()][tgt_pkt->req->masterId()] += 28212726Snikos.nikoleris@arm.com completion_time - target.recvTime; 28312726Snikos.nikoleris@arm.com 28412726Snikos.nikoleris@arm.com tgt_pkt->makeTimingResponse(); 28512726Snikos.nikoleris@arm.com if (pkt->isError()) 28612726Snikos.nikoleris@arm.com tgt_pkt->copyError(pkt); 28712726Snikos.nikoleris@arm.com 28812726Snikos.nikoleris@arm.com // Reset the bus additional time as it is now accounted for 28912726Snikos.nikoleris@arm.com tgt_pkt->headerDelay = tgt_pkt->payloadDelay = 0; 29013564Snikos.nikoleris@arm.com cpuSidePort.schedTimingResp(tgt_pkt, completion_time); 29112726Snikos.nikoleris@arm.com break; 29212726Snikos.nikoleris@arm.com 29312726Snikos.nikoleris@arm.com case MSHR::Target::FromPrefetcher: 29412726Snikos.nikoleris@arm.com // handle deferred requests comming from a prefetcher 29512726Snikos.nikoleris@arm.com // attached to this cache 29612726Snikos.nikoleris@arm.com assert(tgt_pkt->cmd == MemCmd::HardPFReq); 29712726Snikos.nikoleris@arm.com 29812726Snikos.nikoleris@arm.com if (blk) 29912726Snikos.nikoleris@arm.com blk->status |= BlkHWPrefetched; 30012726Snikos.nikoleris@arm.com 30112726Snikos.nikoleris@arm.com // We have filled the block and the prefetcher does not 30212726Snikos.nikoleris@arm.com // require responses. 30312726Snikos.nikoleris@arm.com delete tgt_pkt; 30412726Snikos.nikoleris@arm.com break; 30512726Snikos.nikoleris@arm.com 30612726Snikos.nikoleris@arm.com default: 30712726Snikos.nikoleris@arm.com // we should never see FromSnoop Targets as this is a 30812726Snikos.nikoleris@arm.com // non-coherent cache 30912726Snikos.nikoleris@arm.com panic("Illegal target->source enum %d\n", target.source); 31012726Snikos.nikoleris@arm.com } 31112726Snikos.nikoleris@arm.com } 31212726Snikos.nikoleris@arm.com 31312726Snikos.nikoleris@arm.com // Reponses are filling and bring in writable blocks, therefore 31412726Snikos.nikoleris@arm.com // there should be no deferred targets and all the non-deferred 31512726Snikos.nikoleris@arm.com // targets are now serviced. 31612726Snikos.nikoleris@arm.com assert(mshr->getNumTargets() == 0); 31712726Snikos.nikoleris@arm.com} 31812726Snikos.nikoleris@arm.com 31912726Snikos.nikoleris@arm.comvoid 32012726Snikos.nikoleris@arm.comNoncoherentCache::recvTimingResp(PacketPtr pkt) 32112726Snikos.nikoleris@arm.com{ 32212726Snikos.nikoleris@arm.com assert(pkt->isResponse()); 32312726Snikos.nikoleris@arm.com // At the moment the only supported downstream requests we issue 32412726Snikos.nikoleris@arm.com // are ReadReq and therefore here we should only see the 32512726Snikos.nikoleris@arm.com // corresponding responses 32612726Snikos.nikoleris@arm.com assert(pkt->isRead()); 32712726Snikos.nikoleris@arm.com assert(pkt->cmd != MemCmd::UpgradeResp); 32812726Snikos.nikoleris@arm.com assert(!pkt->isInvalidate()); 32912726Snikos.nikoleris@arm.com // This cache is non-coherent and any memories below are 33012726Snikos.nikoleris@arm.com // non-coherent too (non-coherent caches or the main memory), 33112726Snikos.nikoleris@arm.com // therefore the fetched block can be marked as writable. 33212726Snikos.nikoleris@arm.com assert(!pkt->hasSharers()); 33312726Snikos.nikoleris@arm.com 33412726Snikos.nikoleris@arm.com BaseCache::recvTimingResp(pkt); 33512726Snikos.nikoleris@arm.com} 33612726Snikos.nikoleris@arm.com 33712726Snikos.nikoleris@arm.comPacketPtr 33812726Snikos.nikoleris@arm.comNoncoherentCache::evictBlock(CacheBlk *blk) 33912726Snikos.nikoleris@arm.com{ 34012726Snikos.nikoleris@arm.com // A dirty block is always written back. 34112726Snikos.nikoleris@arm.com 34212726Snikos.nikoleris@arm.com // A clean block can we written back, if we turned on writebacks 34312726Snikos.nikoleris@arm.com // for clean blocks. This could be useful if there is a cache 34412726Snikos.nikoleris@arm.com // below and we want to make sure the block is cached but if the 34512726Snikos.nikoleris@arm.com // memory below is the main memory WritebackCleans are 34612726Snikos.nikoleris@arm.com // unnecessary. 34712726Snikos.nikoleris@arm.com 34812726Snikos.nikoleris@arm.com // If we clean writebacks are not enabled, we do not take any 34912726Snikos.nikoleris@arm.com // further action for evictions of clean blocks (i.e., CleanEvicts 35012726Snikos.nikoleris@arm.com // are unnecessary). 35112726Snikos.nikoleris@arm.com PacketPtr pkt = (blk->isDirty() || writebackClean) ? 35212726Snikos.nikoleris@arm.com writebackBlk(blk) : nullptr; 35312726Snikos.nikoleris@arm.com 35412726Snikos.nikoleris@arm.com invalidateBlock(blk); 35512726Snikos.nikoleris@arm.com 35612726Snikos.nikoleris@arm.com return pkt; 35712726Snikos.nikoleris@arm.com} 35812726Snikos.nikoleris@arm.com 35912726Snikos.nikoleris@arm.comNoncoherentCache* 36012726Snikos.nikoleris@arm.comNoncoherentCacheParams::create() 36112726Snikos.nikoleris@arm.com{ 36212726Snikos.nikoleris@arm.com assert(tags); 36312726Snikos.nikoleris@arm.com assert(replacement_policy); 36412726Snikos.nikoleris@arm.com 36512726Snikos.nikoleris@arm.com return new NoncoherentCache(this); 36612726Snikos.nikoleris@arm.com} 367