base.hh revision 12724
12810SN/A/* 212724Snikos.nikoleris@arm.com * Copyright (c) 2012-2013, 2015-2016, 2018 ARM Limited 38856Sandreas.hansson@arm.com * All rights reserved. 48856Sandreas.hansson@arm.com * 58856Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68856Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78856Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88856Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98856Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108856Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118856Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128856Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138856Sandreas.hansson@arm.com * 142810SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 152810SN/A * All rights reserved. 162810SN/A * 172810SN/A * Redistribution and use in source and binary forms, with or without 182810SN/A * modification, are permitted provided that the following conditions are 192810SN/A * met: redistributions of source code must retain the above copyright 202810SN/A * notice, this list of conditions and the following disclaimer; 212810SN/A * redistributions in binary form must reproduce the above copyright 222810SN/A * notice, this list of conditions and the following disclaimer in the 232810SN/A * documentation and/or other materials provided with the distribution; 242810SN/A * neither the name of the copyright holders nor the names of its 252810SN/A * contributors may be used to endorse or promote products derived from 262810SN/A * this software without specific prior written permission. 272810SN/A * 282810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392810SN/A * 402810SN/A * Authors: Erik Hallnor 414458SN/A * Steve Reinhardt 424458SN/A * Ron Dreslinski 4312724Snikos.nikoleris@arm.com * Andreas Hansson 4412724Snikos.nikoleris@arm.com * Nikos Nikoleris 452810SN/A */ 462810SN/A 472810SN/A/** 482810SN/A * @file 492810SN/A * Declares a basic cache interface BaseCache. 502810SN/A */ 512810SN/A 5211051Sandreas.hansson@arm.com#ifndef __MEM_CACHE_BASE_HH__ 5311051Sandreas.hansson@arm.com#define __MEM_CACHE_BASE_HH__ 542810SN/A 5512724Snikos.nikoleris@arm.com#include <cassert> 5612724Snikos.nikoleris@arm.com#include <cstdint> 577676Snate@binkert.org#include <string> 582810SN/A 5912724Snikos.nikoleris@arm.com#include "base/addr_range.hh" 602810SN/A#include "base/statistics.hh" 612810SN/A#include "base/trace.hh" 626215Snate@binkert.org#include "base/types.hh" 638232Snate@binkert.org#include "debug/Cache.hh" 648232Snate@binkert.org#include "debug/CachePort.hh" 6512724Snikos.nikoleris@arm.com#include "enums/Clusivity.hh" 6612724Snikos.nikoleris@arm.com#include "mem/cache/blk.hh" 675338Sstever@gmail.com#include "mem/cache/mshr_queue.hh" 6812724Snikos.nikoleris@arm.com#include "mem/cache/tags/base.hh" 6911375Sandreas.hansson@arm.com#include "mem/cache/write_queue.hh" 7012724Snikos.nikoleris@arm.com#include "mem/cache/write_queue_entry.hh" 712810SN/A#include "mem/mem_object.hh" 722810SN/A#include "mem/packet.hh" 7312724Snikos.nikoleris@arm.com#include "mem/packet_queue.hh" 748914Sandreas.hansson@arm.com#include "mem/qport.hh" 758229Snate@binkert.org#include "mem/request.hh" 762811SN/A#include "sim/eventq.hh" 7712724Snikos.nikoleris@arm.com#include "sim/serialize.hh" 784626SN/A#include "sim/sim_exit.hh" 798833Sdam.sunwoo@arm.com#include "sim/system.hh" 802810SN/A 8112724Snikos.nikoleris@arm.comclass BaseMasterPort; 8212724Snikos.nikoleris@arm.comclass BasePrefetcher; 8312724Snikos.nikoleris@arm.comclass BaseSlavePort; 8412724Snikos.nikoleris@arm.comclass MSHR; 8512724Snikos.nikoleris@arm.comclass MasterPort; 8612724Snikos.nikoleris@arm.comclass QueueEntry; 8712724Snikos.nikoleris@arm.comstruct BaseCacheParams; 8812724Snikos.nikoleris@arm.com 892810SN/A/** 902810SN/A * A basic cache interface. Implements some common functions for speed. 912810SN/A */ 922810SN/Aclass BaseCache : public MemObject 932810SN/A{ 9411375Sandreas.hansson@arm.com protected: 954628SN/A /** 964628SN/A * Indexes to enumerate the MSHR queues. 974628SN/A */ 984628SN/A enum MSHRQueueIndex { 994628SN/A MSHRQueue_MSHRs, 1004628SN/A MSHRQueue_WriteBuffer 1014628SN/A }; 1024628SN/A 1038737Skoansin.tan@gmail.com public: 1044628SN/A /** 1054628SN/A * Reasons for caches to be blocked. 1064628SN/A */ 1074628SN/A enum BlockedCause { 1084628SN/A Blocked_NoMSHRs = MSHRQueue_MSHRs, 1094628SN/A Blocked_NoWBBuffers = MSHRQueue_WriteBuffer, 1104628SN/A Blocked_NoTargets, 1114628SN/A NUM_BLOCKED_CAUSES 1124628SN/A }; 1134628SN/A 1148737Skoansin.tan@gmail.com protected: 1154628SN/A 1168856Sandreas.hansson@arm.com /** 1178856Sandreas.hansson@arm.com * A cache master port is used for the memory-side port of the 1188856Sandreas.hansson@arm.com * cache, and in addition to the basic timing port that only sends 1198856Sandreas.hansson@arm.com * response packets through a transmit list, it also offers the 1208856Sandreas.hansson@arm.com * ability to schedule and send request packets (requests & 12110942Sandreas.hansson@arm.com * writebacks). The send event is scheduled through schedSendEvent, 1228856Sandreas.hansson@arm.com * and the sendDeferredPacket of the timing port is modified to 1238856Sandreas.hansson@arm.com * consider both the transmit list and the requests from the MSHR. 1248856Sandreas.hansson@arm.com */ 1258922Swilliam.wang@arm.com class CacheMasterPort : public QueuedMasterPort 1262810SN/A { 1278856Sandreas.hansson@arm.com 1282844SN/A public: 1298856Sandreas.hansson@arm.com 1308856Sandreas.hansson@arm.com /** 1318856Sandreas.hansson@arm.com * Schedule a send of a request packet (from the MSHR). Note 13210713Sandreas.hansson@arm.com * that we could already have a retry outstanding. 1338856Sandreas.hansson@arm.com */ 13410942Sandreas.hansson@arm.com void schedSendEvent(Tick time) 1358856Sandreas.hansson@arm.com { 13610942Sandreas.hansson@arm.com DPRINTF(CachePort, "Scheduling send event at %llu\n", time); 13710713Sandreas.hansson@arm.com reqQueue.schedSendEvent(time); 1388856Sandreas.hansson@arm.com } 1398856Sandreas.hansson@arm.com 1403738SN/A protected: 1414458SN/A 1428856Sandreas.hansson@arm.com CacheMasterPort(const std::string &_name, BaseCache *_cache, 14310713Sandreas.hansson@arm.com ReqPacketQueue &_reqQueue, 14410713Sandreas.hansson@arm.com SnoopRespPacketQueue &_snoopRespQueue) : 14510713Sandreas.hansson@arm.com QueuedMasterPort(_name, _cache, _reqQueue, _snoopRespQueue) 1468914Sandreas.hansson@arm.com { } 1472810SN/A 1488856Sandreas.hansson@arm.com /** 1498856Sandreas.hansson@arm.com * Memory-side port always snoops. 1508856Sandreas.hansson@arm.com * 1518914Sandreas.hansson@arm.com * @return always true 1528856Sandreas.hansson@arm.com */ 1538922Swilliam.wang@arm.com virtual bool isSnooping() const { return true; } 1548856Sandreas.hansson@arm.com }; 1553013SN/A 1568856Sandreas.hansson@arm.com /** 15712724Snikos.nikoleris@arm.com * Override the default behaviour of sendDeferredPacket to enable 15812724Snikos.nikoleris@arm.com * the memory-side cache port to also send requests based on the 15912724Snikos.nikoleris@arm.com * current MSHR status. This queue has a pointer to our specific 16012724Snikos.nikoleris@arm.com * cache implementation and is used by the MemSidePort. 16112724Snikos.nikoleris@arm.com */ 16212724Snikos.nikoleris@arm.com class CacheReqPacketQueue : public ReqPacketQueue 16312724Snikos.nikoleris@arm.com { 16412724Snikos.nikoleris@arm.com 16512724Snikos.nikoleris@arm.com protected: 16612724Snikos.nikoleris@arm.com 16712724Snikos.nikoleris@arm.com BaseCache &cache; 16812724Snikos.nikoleris@arm.com SnoopRespPacketQueue &snoopRespQueue; 16912724Snikos.nikoleris@arm.com 17012724Snikos.nikoleris@arm.com public: 17112724Snikos.nikoleris@arm.com 17212724Snikos.nikoleris@arm.com CacheReqPacketQueue(BaseCache &cache, MasterPort &port, 17312724Snikos.nikoleris@arm.com SnoopRespPacketQueue &snoop_resp_queue, 17412724Snikos.nikoleris@arm.com const std::string &label) : 17512724Snikos.nikoleris@arm.com ReqPacketQueue(cache, port, label), cache(cache), 17612724Snikos.nikoleris@arm.com snoopRespQueue(snoop_resp_queue) { } 17712724Snikos.nikoleris@arm.com 17812724Snikos.nikoleris@arm.com /** 17912724Snikos.nikoleris@arm.com * Override the normal sendDeferredPacket and do not only 18012724Snikos.nikoleris@arm.com * consider the transmit list (used for responses), but also 18112724Snikos.nikoleris@arm.com * requests. 18212724Snikos.nikoleris@arm.com */ 18312724Snikos.nikoleris@arm.com virtual void sendDeferredPacket(); 18412724Snikos.nikoleris@arm.com 18512724Snikos.nikoleris@arm.com /** 18612724Snikos.nikoleris@arm.com * Check if there is a conflicting snoop response about to be 18712724Snikos.nikoleris@arm.com * send out, and if so simply stall any requests, and schedule 18812724Snikos.nikoleris@arm.com * a send event at the same time as the next snoop response is 18912724Snikos.nikoleris@arm.com * being sent out. 19012724Snikos.nikoleris@arm.com */ 19112724Snikos.nikoleris@arm.com bool checkConflictingSnoop(Addr addr) 19212724Snikos.nikoleris@arm.com { 19312724Snikos.nikoleris@arm.com if (snoopRespQueue.hasAddr(addr)) { 19412724Snikos.nikoleris@arm.com DPRINTF(CachePort, "Waiting for snoop response to be " 19512724Snikos.nikoleris@arm.com "sent\n"); 19612724Snikos.nikoleris@arm.com Tick when = snoopRespQueue.deferredPacketReadyTime(); 19712724Snikos.nikoleris@arm.com schedSendEvent(when); 19812724Snikos.nikoleris@arm.com return true; 19912724Snikos.nikoleris@arm.com } 20012724Snikos.nikoleris@arm.com return false; 20112724Snikos.nikoleris@arm.com } 20212724Snikos.nikoleris@arm.com }; 20312724Snikos.nikoleris@arm.com 20412724Snikos.nikoleris@arm.com 20512724Snikos.nikoleris@arm.com /** 20612724Snikos.nikoleris@arm.com * The memory-side port extends the base cache master port with 20712724Snikos.nikoleris@arm.com * access functions for functional, atomic and timing snoops. 20812724Snikos.nikoleris@arm.com */ 20912724Snikos.nikoleris@arm.com class MemSidePort : public CacheMasterPort 21012724Snikos.nikoleris@arm.com { 21112724Snikos.nikoleris@arm.com private: 21212724Snikos.nikoleris@arm.com 21312724Snikos.nikoleris@arm.com /** The cache-specific queue. */ 21412724Snikos.nikoleris@arm.com CacheReqPacketQueue _reqQueue; 21512724Snikos.nikoleris@arm.com 21612724Snikos.nikoleris@arm.com SnoopRespPacketQueue _snoopRespQueue; 21712724Snikos.nikoleris@arm.com 21812724Snikos.nikoleris@arm.com // a pointer to our specific cache implementation 21912724Snikos.nikoleris@arm.com BaseCache *cache; 22012724Snikos.nikoleris@arm.com 22112724Snikos.nikoleris@arm.com protected: 22212724Snikos.nikoleris@arm.com 22312724Snikos.nikoleris@arm.com virtual void recvTimingSnoopReq(PacketPtr pkt); 22412724Snikos.nikoleris@arm.com 22512724Snikos.nikoleris@arm.com virtual bool recvTimingResp(PacketPtr pkt); 22612724Snikos.nikoleris@arm.com 22712724Snikos.nikoleris@arm.com virtual Tick recvAtomicSnoop(PacketPtr pkt); 22812724Snikos.nikoleris@arm.com 22912724Snikos.nikoleris@arm.com virtual void recvFunctionalSnoop(PacketPtr pkt); 23012724Snikos.nikoleris@arm.com 23112724Snikos.nikoleris@arm.com public: 23212724Snikos.nikoleris@arm.com 23312724Snikos.nikoleris@arm.com MemSidePort(const std::string &_name, BaseCache *_cache, 23412724Snikos.nikoleris@arm.com const std::string &_label); 23512724Snikos.nikoleris@arm.com }; 23612724Snikos.nikoleris@arm.com 23712724Snikos.nikoleris@arm.com /** 2388856Sandreas.hansson@arm.com * A cache slave port is used for the CPU-side port of the cache, 2398856Sandreas.hansson@arm.com * and it is basically a simple timing port that uses a transmit 2408856Sandreas.hansson@arm.com * list for responses to the CPU (or connected master). In 2418856Sandreas.hansson@arm.com * addition, it has the functionality to block the port for 2428856Sandreas.hansson@arm.com * incoming requests. If blocked, the port will issue a retry once 2438856Sandreas.hansson@arm.com * unblocked. 2448856Sandreas.hansson@arm.com */ 2458922Swilliam.wang@arm.com class CacheSlavePort : public QueuedSlavePort 2468856Sandreas.hansson@arm.com { 2475314SN/A 2482811SN/A public: 2498856Sandreas.hansson@arm.com 2508856Sandreas.hansson@arm.com /** Do not accept any new requests. */ 2512810SN/A void setBlocked(); 2522810SN/A 2538856Sandreas.hansson@arm.com /** Return to normal operation and accept new requests. */ 2542810SN/A void clearBlocked(); 2552810SN/A 25610345SCurtis.Dunham@arm.com bool isBlocked() const { return blocked; } 25710345SCurtis.Dunham@arm.com 2588856Sandreas.hansson@arm.com protected: 2598856Sandreas.hansson@arm.com 2608856Sandreas.hansson@arm.com CacheSlavePort(const std::string &_name, BaseCache *_cache, 2618856Sandreas.hansson@arm.com const std::string &_label); 2623606SN/A 2638914Sandreas.hansson@arm.com /** A normal packet queue used to store responses. */ 26410713Sandreas.hansson@arm.com RespPacketQueue queue; 2658914Sandreas.hansson@arm.com 2662810SN/A bool blocked; 2672810SN/A 2682897SN/A bool mustSendRetry; 2692897SN/A 2708856Sandreas.hansson@arm.com private: 2714458SN/A 27210344Sandreas.hansson@arm.com void processSendRetry(); 27310344Sandreas.hansson@arm.com 27412084Sspwilson2@wisc.edu EventFunctionWrapper sendRetryEvent; 2758856Sandreas.hansson@arm.com 2762811SN/A }; 2772810SN/A 27812724Snikos.nikoleris@arm.com /** 27912724Snikos.nikoleris@arm.com * The CPU-side port extends the base cache slave port with access 28012724Snikos.nikoleris@arm.com * functions for functional, atomic and timing requests. 28112724Snikos.nikoleris@arm.com */ 28212724Snikos.nikoleris@arm.com class CpuSidePort : public CacheSlavePort 28312724Snikos.nikoleris@arm.com { 28412724Snikos.nikoleris@arm.com private: 28512724Snikos.nikoleris@arm.com 28612724Snikos.nikoleris@arm.com // a pointer to our specific cache implementation 28712724Snikos.nikoleris@arm.com BaseCache *cache; 28812724Snikos.nikoleris@arm.com 28912724Snikos.nikoleris@arm.com protected: 29012724Snikos.nikoleris@arm.com virtual bool recvTimingSnoopResp(PacketPtr pkt) override; 29112724Snikos.nikoleris@arm.com 29212724Snikos.nikoleris@arm.com virtual bool tryTiming(PacketPtr pkt) override; 29312724Snikos.nikoleris@arm.com 29412724Snikos.nikoleris@arm.com virtual bool recvTimingReq(PacketPtr pkt) override; 29512724Snikos.nikoleris@arm.com 29612724Snikos.nikoleris@arm.com virtual Tick recvAtomic(PacketPtr pkt) override; 29712724Snikos.nikoleris@arm.com 29812724Snikos.nikoleris@arm.com virtual void recvFunctional(PacketPtr pkt) override; 29912724Snikos.nikoleris@arm.com 30012724Snikos.nikoleris@arm.com virtual AddrRangeList getAddrRanges() const override; 30112724Snikos.nikoleris@arm.com 30212724Snikos.nikoleris@arm.com public: 30312724Snikos.nikoleris@arm.com 30412724Snikos.nikoleris@arm.com CpuSidePort(const std::string &_name, BaseCache *_cache, 30512724Snikos.nikoleris@arm.com const std::string &_label); 30612724Snikos.nikoleris@arm.com 30712724Snikos.nikoleris@arm.com }; 30812724Snikos.nikoleris@arm.com 30912724Snikos.nikoleris@arm.com CpuSidePort cpuSidePort; 31012724Snikos.nikoleris@arm.com MemSidePort memSidePort; 3113338SN/A 3124626SN/A protected: 3134626SN/A 3144626SN/A /** Miss status registers */ 3154626SN/A MSHRQueue mshrQueue; 3164626SN/A 3174626SN/A /** Write/writeback buffer */ 31811375Sandreas.hansson@arm.com WriteQueue writeBuffer; 3194626SN/A 32012724Snikos.nikoleris@arm.com /** Tag and data Storage */ 32112724Snikos.nikoleris@arm.com BaseTags *tags; 32212724Snikos.nikoleris@arm.com 32312724Snikos.nikoleris@arm.com /** Prefetcher */ 32412724Snikos.nikoleris@arm.com BasePrefetcher *prefetcher; 32512724Snikos.nikoleris@arm.com 32612724Snikos.nikoleris@arm.com /** 32712724Snikos.nikoleris@arm.com * Notify the prefetcher on every access, not just misses. 32812724Snikos.nikoleris@arm.com */ 32912724Snikos.nikoleris@arm.com const bool prefetchOnAccess; 33012724Snikos.nikoleris@arm.com 33112724Snikos.nikoleris@arm.com /** 33212724Snikos.nikoleris@arm.com * Temporary cache block for occasional transitory use. We use 33312724Snikos.nikoleris@arm.com * the tempBlock to fill when allocation fails (e.g., when there 33412724Snikos.nikoleris@arm.com * is an outstanding request that accesses the victim block) or 33512724Snikos.nikoleris@arm.com * when we want to avoid allocation (e.g., exclusive caches) 33612724Snikos.nikoleris@arm.com */ 33712724Snikos.nikoleris@arm.com CacheBlk *tempBlock; 33812724Snikos.nikoleris@arm.com 33912724Snikos.nikoleris@arm.com /** 34012724Snikos.nikoleris@arm.com * Upstream caches need this packet until true is returned, so 34112724Snikos.nikoleris@arm.com * hold it for deletion until a subsequent call 34212724Snikos.nikoleris@arm.com */ 34312724Snikos.nikoleris@arm.com std::unique_ptr<Packet> pendingDelete; 34412724Snikos.nikoleris@arm.com 34510693SMarco.Balboni@ARM.com /** 34611375Sandreas.hansson@arm.com * Mark a request as in service (sent downstream in the memory 34711375Sandreas.hansson@arm.com * system), effectively making this MSHR the ordering point. 34810693SMarco.Balboni@ARM.com */ 34911375Sandreas.hansson@arm.com void markInService(MSHR *mshr, bool pending_modified_resp) 3504628SN/A { 35111375Sandreas.hansson@arm.com bool wasFull = mshrQueue.isFull(); 35211375Sandreas.hansson@arm.com mshrQueue.markInService(mshr, pending_modified_resp); 35310764Sandreas.hansson@arm.com 35411375Sandreas.hansson@arm.com if (wasFull && !mshrQueue.isFull()) { 35511375Sandreas.hansson@arm.com clearBlocked(Blocked_NoMSHRs); 3564628SN/A } 3574628SN/A } 3584628SN/A 35911375Sandreas.hansson@arm.com void markInService(WriteQueueEntry *entry) 3604628SN/A { 36111375Sandreas.hansson@arm.com bool wasFull = writeBuffer.isFull(); 36211375Sandreas.hansson@arm.com writeBuffer.markInService(entry); 36311375Sandreas.hansson@arm.com 36411375Sandreas.hansson@arm.com if (wasFull && !writeBuffer.isFull()) { 36511375Sandreas.hansson@arm.com clearBlocked(Blocked_NoWBBuffers); 3664628SN/A } 3674628SN/A } 3684628SN/A 3699347SAndreas.Sandberg@arm.com /** 37012724Snikos.nikoleris@arm.com * Determine whether we should allocate on a fill or not. If this 37112724Snikos.nikoleris@arm.com * cache is mostly inclusive with regards to the upstream cache(s) 37212724Snikos.nikoleris@arm.com * we always allocate (for any non-forwarded and cacheable 37312724Snikos.nikoleris@arm.com * requests). In the case of a mostly exclusive cache, we allocate 37412724Snikos.nikoleris@arm.com * on fill if the packet did not come from a cache, thus if we: 37512724Snikos.nikoleris@arm.com * are dealing with a whole-line write (the latter behaves much 37612724Snikos.nikoleris@arm.com * like a writeback), the original target packet came from a 37712724Snikos.nikoleris@arm.com * non-caching source, or if we are performing a prefetch or LLSC. 37811197Sandreas.hansson@arm.com * 37912724Snikos.nikoleris@arm.com * @param cmd Command of the incoming requesting packet 38012724Snikos.nikoleris@arm.com * @return Whether we should allocate on the fill 38112724Snikos.nikoleris@arm.com */ 38212724Snikos.nikoleris@arm.com inline bool allocOnFill(MemCmd cmd) const 38312724Snikos.nikoleris@arm.com { 38412724Snikos.nikoleris@arm.com return clusivity == Enums::mostly_incl || 38512724Snikos.nikoleris@arm.com cmd == MemCmd::WriteLineReq || 38612724Snikos.nikoleris@arm.com cmd == MemCmd::ReadReq || 38712724Snikos.nikoleris@arm.com cmd == MemCmd::WriteReq || 38812724Snikos.nikoleris@arm.com cmd.isPrefetch() || 38912724Snikos.nikoleris@arm.com cmd.isLLSC(); 39012724Snikos.nikoleris@arm.com } 39112724Snikos.nikoleris@arm.com 39212724Snikos.nikoleris@arm.com /** 39312724Snikos.nikoleris@arm.com * Does all the processing necessary to perform the provided request. 39412724Snikos.nikoleris@arm.com * @param pkt The memory request to perform. 39512724Snikos.nikoleris@arm.com * @param blk The cache block to be updated. 39612724Snikos.nikoleris@arm.com * @param lat The latency of the access. 39712724Snikos.nikoleris@arm.com * @param writebacks List for any writebacks that need to be performed. 39812724Snikos.nikoleris@arm.com * @return Boolean indicating whether the request was satisfied. 39912724Snikos.nikoleris@arm.com */ 40012724Snikos.nikoleris@arm.com virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, 40112724Snikos.nikoleris@arm.com PacketList &writebacks); 40212724Snikos.nikoleris@arm.com 40312724Snikos.nikoleris@arm.com /* 40412724Snikos.nikoleris@arm.com * Handle a timing request that hit in the cache 40511197Sandreas.hansson@arm.com * 40612724Snikos.nikoleris@arm.com * @param ptk The request packet 40712724Snikos.nikoleris@arm.com * @param blk The referenced block 40812724Snikos.nikoleris@arm.com * @param request_time The tick at which the block lookup is compete 40911197Sandreas.hansson@arm.com */ 41012724Snikos.nikoleris@arm.com virtual void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, 41112724Snikos.nikoleris@arm.com Tick request_time); 41212724Snikos.nikoleris@arm.com 41312724Snikos.nikoleris@arm.com /* 41412724Snikos.nikoleris@arm.com * Handle a timing request that missed in the cache 41512724Snikos.nikoleris@arm.com * 41612724Snikos.nikoleris@arm.com * Implementation specific handling for different cache 41712724Snikos.nikoleris@arm.com * implementations 41812724Snikos.nikoleris@arm.com * 41912724Snikos.nikoleris@arm.com * @param ptk The request packet 42012724Snikos.nikoleris@arm.com * @param blk The referenced block 42112724Snikos.nikoleris@arm.com * @param forward_time The tick at which we can process dependent requests 42212724Snikos.nikoleris@arm.com * @param request_time The tick at which the block lookup is compete 42312724Snikos.nikoleris@arm.com */ 42412724Snikos.nikoleris@arm.com virtual void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, 42512724Snikos.nikoleris@arm.com Tick forward_time, 42612724Snikos.nikoleris@arm.com Tick request_time) = 0; 42712724Snikos.nikoleris@arm.com 42812724Snikos.nikoleris@arm.com /* 42912724Snikos.nikoleris@arm.com * Handle a timing request that missed in the cache 43012724Snikos.nikoleris@arm.com * 43112724Snikos.nikoleris@arm.com * Common functionality across different cache implementations 43212724Snikos.nikoleris@arm.com * 43312724Snikos.nikoleris@arm.com * @param ptk The request packet 43412724Snikos.nikoleris@arm.com * @param blk The referenced block 43512724Snikos.nikoleris@arm.com * @param mshr Any existing mshr for the referenced cache block 43612724Snikos.nikoleris@arm.com * @param forward_time The tick at which we can process dependent requests 43712724Snikos.nikoleris@arm.com * @param request_time The tick at which the block lookup is compete 43812724Snikos.nikoleris@arm.com */ 43912724Snikos.nikoleris@arm.com void handleTimingReqMiss(PacketPtr pkt, MSHR *mshr, CacheBlk *blk, 44012724Snikos.nikoleris@arm.com Tick forward_time, Tick request_time); 44112724Snikos.nikoleris@arm.com 44212724Snikos.nikoleris@arm.com /** 44312724Snikos.nikoleris@arm.com * Performs the access specified by the request. 44412724Snikos.nikoleris@arm.com * @param pkt The request to perform. 44512724Snikos.nikoleris@arm.com */ 44612724Snikos.nikoleris@arm.com virtual void recvTimingReq(PacketPtr pkt); 44712724Snikos.nikoleris@arm.com 44812724Snikos.nikoleris@arm.com /** 44912724Snikos.nikoleris@arm.com * Handling the special case of uncacheable write responses to 45012724Snikos.nikoleris@arm.com * make recvTimingResp less cluttered. 45112724Snikos.nikoleris@arm.com */ 45212724Snikos.nikoleris@arm.com void handleUncacheableWriteResp(PacketPtr pkt); 45312724Snikos.nikoleris@arm.com 45412724Snikos.nikoleris@arm.com /** 45512724Snikos.nikoleris@arm.com * Service non-deferred MSHR targets using the received response 45612724Snikos.nikoleris@arm.com * 45712724Snikos.nikoleris@arm.com * Iterates through the list of targets that can be serviced with 45812724Snikos.nikoleris@arm.com * the current response. Any writebacks that need to performed 45912724Snikos.nikoleris@arm.com * must be appended to the writebacks parameter. 46012724Snikos.nikoleris@arm.com * 46112724Snikos.nikoleris@arm.com * @param mshr The MSHR that corresponds to the reponse 46212724Snikos.nikoleris@arm.com * @param pkt The response packet 46312724Snikos.nikoleris@arm.com * @param blk The reference block 46412724Snikos.nikoleris@arm.com * @param writebacks List of writebacks that need to be performed 46512724Snikos.nikoleris@arm.com */ 46612724Snikos.nikoleris@arm.com virtual void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, 46712724Snikos.nikoleris@arm.com CacheBlk *blk, PacketList& writebacks) = 0; 46812724Snikos.nikoleris@arm.com 46912724Snikos.nikoleris@arm.com /** 47012724Snikos.nikoleris@arm.com * Handles a response (cache line fill/write ack) from the bus. 47112724Snikos.nikoleris@arm.com * @param pkt The response packet 47212724Snikos.nikoleris@arm.com */ 47312724Snikos.nikoleris@arm.com virtual void recvTimingResp(PacketPtr pkt); 47412724Snikos.nikoleris@arm.com 47512724Snikos.nikoleris@arm.com /** 47612724Snikos.nikoleris@arm.com * Snoops bus transactions to maintain coherence. 47712724Snikos.nikoleris@arm.com * @param pkt The current bus transaction. 47812724Snikos.nikoleris@arm.com */ 47912724Snikos.nikoleris@arm.com virtual void recvTimingSnoopReq(PacketPtr pkt) = 0; 48012724Snikos.nikoleris@arm.com 48112724Snikos.nikoleris@arm.com /** 48212724Snikos.nikoleris@arm.com * Handle a snoop response. 48312724Snikos.nikoleris@arm.com * @param pkt Snoop response packet 48412724Snikos.nikoleris@arm.com */ 48512724Snikos.nikoleris@arm.com virtual void recvTimingSnoopResp(PacketPtr pkt) = 0; 48612724Snikos.nikoleris@arm.com 48712724Snikos.nikoleris@arm.com /** 48812724Snikos.nikoleris@arm.com * Handle a request in atomic mode that missed in this cache 48912724Snikos.nikoleris@arm.com * 49012724Snikos.nikoleris@arm.com * Creates a downstream request, sends it to the memory below and 49112724Snikos.nikoleris@arm.com * handles the response. As we are in atomic mode all operations 49212724Snikos.nikoleris@arm.com * are performed immediately. 49312724Snikos.nikoleris@arm.com * 49412724Snikos.nikoleris@arm.com * @param pkt The packet with the requests 49512724Snikos.nikoleris@arm.com * @param blk The referenced block 49612724Snikos.nikoleris@arm.com * @param writebacks A list with packets for any performed writebacks 49712724Snikos.nikoleris@arm.com * @return Cycles for handling the request 49812724Snikos.nikoleris@arm.com */ 49912724Snikos.nikoleris@arm.com virtual Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *blk, 50012724Snikos.nikoleris@arm.com PacketList &writebacks) = 0; 50112724Snikos.nikoleris@arm.com 50212724Snikos.nikoleris@arm.com /** 50312724Snikos.nikoleris@arm.com * Performs the access specified by the request. 50412724Snikos.nikoleris@arm.com * @param pkt The request to perform. 50512724Snikos.nikoleris@arm.com * @return The number of ticks required for the access. 50612724Snikos.nikoleris@arm.com */ 50712724Snikos.nikoleris@arm.com virtual Tick recvAtomic(PacketPtr pkt); 50812724Snikos.nikoleris@arm.com 50912724Snikos.nikoleris@arm.com /** 51012724Snikos.nikoleris@arm.com * Snoop for the provided request in the cache and return the estimated 51112724Snikos.nikoleris@arm.com * time taken. 51212724Snikos.nikoleris@arm.com * @param pkt The memory request to snoop 51312724Snikos.nikoleris@arm.com * @return The number of ticks required for the snoop. 51412724Snikos.nikoleris@arm.com */ 51512724Snikos.nikoleris@arm.com virtual Tick recvAtomicSnoop(PacketPtr pkt) = 0; 51612724Snikos.nikoleris@arm.com 51712724Snikos.nikoleris@arm.com /** 51812724Snikos.nikoleris@arm.com * Performs the access specified by the request. 51912724Snikos.nikoleris@arm.com * 52012724Snikos.nikoleris@arm.com * @param pkt The request to perform. 52112724Snikos.nikoleris@arm.com * @param fromCpuSide from the CPU side port or the memory side port 52212724Snikos.nikoleris@arm.com */ 52312724Snikos.nikoleris@arm.com virtual void functionalAccess(PacketPtr pkt, bool from_cpu_side); 52412724Snikos.nikoleris@arm.com 52512724Snikos.nikoleris@arm.com /** 52612724Snikos.nikoleris@arm.com * Handle doing the Compare and Swap function for SPARC. 52712724Snikos.nikoleris@arm.com */ 52812724Snikos.nikoleris@arm.com void cmpAndSwap(CacheBlk *blk, PacketPtr pkt); 52912724Snikos.nikoleris@arm.com 53012724Snikos.nikoleris@arm.com /** 53112724Snikos.nikoleris@arm.com * Return the next queue entry to service, either a pending miss 53212724Snikos.nikoleris@arm.com * from the MSHR queue, a buffered write from the write buffer, or 53312724Snikos.nikoleris@arm.com * something from the prefetcher. This function is responsible 53412724Snikos.nikoleris@arm.com * for prioritizing among those sources on the fly. 53512724Snikos.nikoleris@arm.com */ 53612724Snikos.nikoleris@arm.com QueueEntry* getNextQueueEntry(); 53712724Snikos.nikoleris@arm.com 53812724Snikos.nikoleris@arm.com /** 53912724Snikos.nikoleris@arm.com * Insert writebacks into the write buffer 54012724Snikos.nikoleris@arm.com */ 54112724Snikos.nikoleris@arm.com virtual void doWritebacks(PacketList& writebacks, Tick forward_time) = 0; 54212724Snikos.nikoleris@arm.com 54312724Snikos.nikoleris@arm.com /** 54412724Snikos.nikoleris@arm.com * Send writebacks down the memory hierarchy in atomic mode 54512724Snikos.nikoleris@arm.com */ 54612724Snikos.nikoleris@arm.com virtual void doWritebacksAtomic(PacketList& writebacks) = 0; 54712724Snikos.nikoleris@arm.com 54812724Snikos.nikoleris@arm.com /** 54912724Snikos.nikoleris@arm.com * Create an appropriate downstream bus request packet. 55012724Snikos.nikoleris@arm.com * 55112724Snikos.nikoleris@arm.com * Creates a new packet with the request to be send to the memory 55212724Snikos.nikoleris@arm.com * below, or nullptr if the current request in cpu_pkt should just 55312724Snikos.nikoleris@arm.com * be forwarded on. 55412724Snikos.nikoleris@arm.com * 55512724Snikos.nikoleris@arm.com * @param cpu_pkt The miss packet that needs to be satisfied. 55612724Snikos.nikoleris@arm.com * @param blk The referenced block, can be nullptr. 55712724Snikos.nikoleris@arm.com * @param needs_writable Indicates that the block must be writable 55812724Snikos.nikoleris@arm.com * even if the request in cpu_pkt doesn't indicate that. 55912724Snikos.nikoleris@arm.com * @return A packet send to the memory below 56012724Snikos.nikoleris@arm.com */ 56112724Snikos.nikoleris@arm.com virtual PacketPtr createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, 56212724Snikos.nikoleris@arm.com bool needs_writable) const = 0; 56312724Snikos.nikoleris@arm.com 56412724Snikos.nikoleris@arm.com /** 56512724Snikos.nikoleris@arm.com * Determine if clean lines should be written back or not. In 56612724Snikos.nikoleris@arm.com * cases where a downstream cache is mostly inclusive we likely 56712724Snikos.nikoleris@arm.com * want it to act as a victim cache also for lines that have not 56812724Snikos.nikoleris@arm.com * been modified. Hence, we cannot simply drop the line (or send a 56912724Snikos.nikoleris@arm.com * clean evict), but rather need to send the actual data. 57012724Snikos.nikoleris@arm.com */ 57112724Snikos.nikoleris@arm.com const bool writebackClean; 57212724Snikos.nikoleris@arm.com 57312724Snikos.nikoleris@arm.com /** 57412724Snikos.nikoleris@arm.com * Writebacks from the tempBlock, resulting on the response path 57512724Snikos.nikoleris@arm.com * in atomic mode, must happen after the call to recvAtomic has 57612724Snikos.nikoleris@arm.com * finished (for the right ordering of the packets). We therefore 57712724Snikos.nikoleris@arm.com * need to hold on to the packets, and have a method and an event 57812724Snikos.nikoleris@arm.com * to send them. 57912724Snikos.nikoleris@arm.com */ 58012724Snikos.nikoleris@arm.com PacketPtr tempBlockWriteback; 58112724Snikos.nikoleris@arm.com 58212724Snikos.nikoleris@arm.com /** 58312724Snikos.nikoleris@arm.com * Send the outstanding tempBlock writeback. To be called after 58412724Snikos.nikoleris@arm.com * recvAtomic finishes in cases where the block we filled is in 58512724Snikos.nikoleris@arm.com * fact the tempBlock, and now needs to be written back. 58612724Snikos.nikoleris@arm.com */ 58712724Snikos.nikoleris@arm.com void writebackTempBlockAtomic() { 58812724Snikos.nikoleris@arm.com assert(tempBlockWriteback != nullptr); 58912724Snikos.nikoleris@arm.com PacketList writebacks{tempBlockWriteback}; 59012724Snikos.nikoleris@arm.com doWritebacksAtomic(writebacks); 59112724Snikos.nikoleris@arm.com tempBlockWriteback = nullptr; 59212724Snikos.nikoleris@arm.com } 59312724Snikos.nikoleris@arm.com 59412724Snikos.nikoleris@arm.com /** 59512724Snikos.nikoleris@arm.com * An event to writeback the tempBlock after recvAtomic 59612724Snikos.nikoleris@arm.com * finishes. To avoid other calls to recvAtomic getting in 59712724Snikos.nikoleris@arm.com * between, we create this event with a higher priority. 59812724Snikos.nikoleris@arm.com */ 59912724Snikos.nikoleris@arm.com EventFunctionWrapper writebackTempBlockAtomicEvent; 60012724Snikos.nikoleris@arm.com 60112724Snikos.nikoleris@arm.com /** 60212724Snikos.nikoleris@arm.com * Perform any necessary updates to the block and perform any data 60312724Snikos.nikoleris@arm.com * exchange between the packet and the block. The flags of the 60412724Snikos.nikoleris@arm.com * packet are also set accordingly. 60512724Snikos.nikoleris@arm.com * 60612724Snikos.nikoleris@arm.com * @param pkt Request packet from upstream that hit a block 60712724Snikos.nikoleris@arm.com * @param blk Cache block that the packet hit 60812724Snikos.nikoleris@arm.com * @param deferred_response Whether this request originally missed 60912724Snikos.nikoleris@arm.com * @param pending_downgrade Whether the writable flag is to be removed 61012724Snikos.nikoleris@arm.com */ 61112724Snikos.nikoleris@arm.com virtual void satisfyRequest(PacketPtr pkt, CacheBlk *blk, 61212724Snikos.nikoleris@arm.com bool deferred_response = false, 61312724Snikos.nikoleris@arm.com bool pending_downgrade = false); 61412724Snikos.nikoleris@arm.com 61512724Snikos.nikoleris@arm.com /** 61612724Snikos.nikoleris@arm.com * Maintain the clusivity of this cache by potentially 61712724Snikos.nikoleris@arm.com * invalidating a block. This method works in conjunction with 61812724Snikos.nikoleris@arm.com * satisfyRequest, but is separate to allow us to handle all MSHR 61912724Snikos.nikoleris@arm.com * targets before potentially dropping a block. 62012724Snikos.nikoleris@arm.com * 62112724Snikos.nikoleris@arm.com * @param from_cache Whether we have dealt with a packet from a cache 62212724Snikos.nikoleris@arm.com * @param blk The block that should potentially be dropped 62312724Snikos.nikoleris@arm.com */ 62412724Snikos.nikoleris@arm.com void maintainClusivity(bool from_cache, CacheBlk *blk); 62512724Snikos.nikoleris@arm.com 62612724Snikos.nikoleris@arm.com /** 62712724Snikos.nikoleris@arm.com * Handle a fill operation caused by a received packet. 62812724Snikos.nikoleris@arm.com * 62912724Snikos.nikoleris@arm.com * Populates a cache block and handles all outstanding requests for the 63012724Snikos.nikoleris@arm.com * satisfied fill request. This version takes two memory requests. One 63112724Snikos.nikoleris@arm.com * contains the fill data, the other is an optional target to satisfy. 63212724Snikos.nikoleris@arm.com * Note that the reason we return a list of writebacks rather than 63312724Snikos.nikoleris@arm.com * inserting them directly in the write buffer is that this function 63412724Snikos.nikoleris@arm.com * is called by both atomic and timing-mode accesses, and in atomic 63512724Snikos.nikoleris@arm.com * mode we don't mess with the write buffer (we just perform the 63612724Snikos.nikoleris@arm.com * writebacks atomically once the original request is complete). 63712724Snikos.nikoleris@arm.com * 63812724Snikos.nikoleris@arm.com * @param pkt The memory request with the fill data. 63912724Snikos.nikoleris@arm.com * @param blk The cache block if it already exists. 64012724Snikos.nikoleris@arm.com * @param writebacks List for any writebacks that need to be performed. 64112724Snikos.nikoleris@arm.com * @param allocate Whether to allocate a block or use the temp block 64212724Snikos.nikoleris@arm.com * @return Pointer to the new cache block. 64312724Snikos.nikoleris@arm.com */ 64412724Snikos.nikoleris@arm.com CacheBlk *handleFill(PacketPtr pkt, CacheBlk *blk, 64512724Snikos.nikoleris@arm.com PacketList &writebacks, bool allocate); 64612724Snikos.nikoleris@arm.com 64712724Snikos.nikoleris@arm.com /** 64812724Snikos.nikoleris@arm.com * Allocate a new block and perform any necessary writebacks 64912724Snikos.nikoleris@arm.com * 65012724Snikos.nikoleris@arm.com * Find a victim block and if necessary prepare writebacks for any 65112724Snikos.nikoleris@arm.com * existing data. May return nullptr if there are no replaceable 65212724Snikos.nikoleris@arm.com * blocks. 65312724Snikos.nikoleris@arm.com * 65412724Snikos.nikoleris@arm.com * @param addr Physical address of the new block 65512724Snikos.nikoleris@arm.com * @param is_secure Set if the block should be secure 65612724Snikos.nikoleris@arm.com * @param writebacks A list of writeback packets for the evicted blocks 65712724Snikos.nikoleris@arm.com * @return the allocated block 65812724Snikos.nikoleris@arm.com */ 65912724Snikos.nikoleris@arm.com CacheBlk *allocateBlock(Addr addr, bool is_secure, PacketList &writebacks); 66012724Snikos.nikoleris@arm.com /** 66112724Snikos.nikoleris@arm.com * Evict a cache block. 66212724Snikos.nikoleris@arm.com * 66312724Snikos.nikoleris@arm.com * Performs a writeback if necesssary and invalidates the block 66412724Snikos.nikoleris@arm.com * 66512724Snikos.nikoleris@arm.com * @param blk Block to invalidate 66612724Snikos.nikoleris@arm.com * @return A packet with the writeback, can be nullptr 66712724Snikos.nikoleris@arm.com */ 66812724Snikos.nikoleris@arm.com M5_NODISCARD virtual PacketPtr evictBlock(CacheBlk *blk) = 0; 66912724Snikos.nikoleris@arm.com 67012724Snikos.nikoleris@arm.com /** 67112724Snikos.nikoleris@arm.com * Evict a cache block. 67212724Snikos.nikoleris@arm.com * 67312724Snikos.nikoleris@arm.com * Performs a writeback if necesssary and invalidates the block 67412724Snikos.nikoleris@arm.com * 67512724Snikos.nikoleris@arm.com * @param blk Block to invalidate 67612724Snikos.nikoleris@arm.com * @param writebacks Return a list of packets with writebacks 67712724Snikos.nikoleris@arm.com */ 67812724Snikos.nikoleris@arm.com virtual void evictBlock(CacheBlk *blk, PacketList &writebacks) = 0; 67912724Snikos.nikoleris@arm.com 68012724Snikos.nikoleris@arm.com /** 68112724Snikos.nikoleris@arm.com * Invalidate a cache block. 68212724Snikos.nikoleris@arm.com * 68312724Snikos.nikoleris@arm.com * @param blk Block to invalidate 68412724Snikos.nikoleris@arm.com */ 68512724Snikos.nikoleris@arm.com void invalidateBlock(CacheBlk *blk); 68612724Snikos.nikoleris@arm.com 68712724Snikos.nikoleris@arm.com /** 68812724Snikos.nikoleris@arm.com * Create a writeback request for the given block. 68912724Snikos.nikoleris@arm.com * 69012724Snikos.nikoleris@arm.com * @param blk The block to writeback. 69112724Snikos.nikoleris@arm.com * @return The writeback request for the block. 69212724Snikos.nikoleris@arm.com */ 69312724Snikos.nikoleris@arm.com PacketPtr writebackBlk(CacheBlk *blk); 69412724Snikos.nikoleris@arm.com 69512724Snikos.nikoleris@arm.com /** 69612724Snikos.nikoleris@arm.com * Create a writeclean request for the given block. 69712724Snikos.nikoleris@arm.com * 69812724Snikos.nikoleris@arm.com * Creates a request that writes the block to the cache below 69912724Snikos.nikoleris@arm.com * without evicting the block from the current cache. 70012724Snikos.nikoleris@arm.com * 70112724Snikos.nikoleris@arm.com * @param blk The block to write clean. 70212724Snikos.nikoleris@arm.com * @param dest The destination of the write clean operation. 70312724Snikos.nikoleris@arm.com * @param id Use the given packet id for the write clean operation. 70412724Snikos.nikoleris@arm.com * @return The generated write clean packet. 70512724Snikos.nikoleris@arm.com */ 70612724Snikos.nikoleris@arm.com PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id); 70711197Sandreas.hansson@arm.com 70811197Sandreas.hansson@arm.com /** 7099347SAndreas.Sandberg@arm.com * Write back dirty blocks in the cache using functional accesses. 7109347SAndreas.Sandberg@arm.com */ 71112724Snikos.nikoleris@arm.com virtual void memWriteback() override; 71212724Snikos.nikoleris@arm.com 7139347SAndreas.Sandberg@arm.com /** 7149347SAndreas.Sandberg@arm.com * Invalidates all blocks in the cache. 7159347SAndreas.Sandberg@arm.com * 7169347SAndreas.Sandberg@arm.com * @warn Dirty cache lines will not be written back to 7179347SAndreas.Sandberg@arm.com * memory. Make sure to call functionalWriteback() first if you 7189347SAndreas.Sandberg@arm.com * want the to write them to memory. 7199347SAndreas.Sandberg@arm.com */ 72012724Snikos.nikoleris@arm.com virtual void memInvalidate() override; 72112724Snikos.nikoleris@arm.com 7229347SAndreas.Sandberg@arm.com /** 7239347SAndreas.Sandberg@arm.com * Determine if there are any dirty blocks in the cache. 7249347SAndreas.Sandberg@arm.com * 72512724Snikos.nikoleris@arm.com * @return true if at least one block is dirty, false otherwise. 7269347SAndreas.Sandberg@arm.com */ 72712724Snikos.nikoleris@arm.com bool isDirty() const; 7289347SAndreas.Sandberg@arm.com 72910821Sandreas.hansson@arm.com /** 73010821Sandreas.hansson@arm.com * Determine if an address is in the ranges covered by this 73110821Sandreas.hansson@arm.com * cache. This is useful to filter snoops. 73210821Sandreas.hansson@arm.com * 73310821Sandreas.hansson@arm.com * @param addr Address to check against 73410821Sandreas.hansson@arm.com * 73510821Sandreas.hansson@arm.com * @return If the address in question is in range 73610821Sandreas.hansson@arm.com */ 73710821Sandreas.hansson@arm.com bool inRange(Addr addr) const; 73810821Sandreas.hansson@arm.com 73912724Snikos.nikoleris@arm.com /** 74012724Snikos.nikoleris@arm.com * Find next request ready time from among possible sources. 74112724Snikos.nikoleris@arm.com */ 74212724Snikos.nikoleris@arm.com Tick nextQueueReadyTime() const; 74312724Snikos.nikoleris@arm.com 7444626SN/A /** Block size of this cache */ 7456227Snate@binkert.org const unsigned blkSize; 7464626SN/A 7474630SN/A /** 74810693SMarco.Balboni@ARM.com * The latency of tag lookup of a cache. It occurs when there is 74910693SMarco.Balboni@ARM.com * an access to the cache. 7504630SN/A */ 75110693SMarco.Balboni@ARM.com const Cycles lookupLatency; 7529263Smrinmoy.ghosh@arm.com 7539263Smrinmoy.ghosh@arm.com /** 75411722Ssophiane.senni@gmail.com * The latency of data access of a cache. It occurs when there is 75511722Ssophiane.senni@gmail.com * an access to the cache. 75611722Ssophiane.senni@gmail.com */ 75711722Ssophiane.senni@gmail.com const Cycles dataLatency; 75811722Ssophiane.senni@gmail.com 75911722Ssophiane.senni@gmail.com /** 76010693SMarco.Balboni@ARM.com * This is the forward latency of the cache. It occurs when there 76110693SMarco.Balboni@ARM.com * is a cache miss and a request is forwarded downstream, in 76210693SMarco.Balboni@ARM.com * particular an outbound miss. 76310693SMarco.Balboni@ARM.com */ 76410693SMarco.Balboni@ARM.com const Cycles forwardLatency; 76510693SMarco.Balboni@ARM.com 76610693SMarco.Balboni@ARM.com /** The latency to fill a cache block */ 76710693SMarco.Balboni@ARM.com const Cycles fillLatency; 76810693SMarco.Balboni@ARM.com 76910693SMarco.Balboni@ARM.com /** 77010693SMarco.Balboni@ARM.com * The latency of sending reponse to its upper level cache/core on 77110693SMarco.Balboni@ARM.com * a linefill. The responseLatency parameter captures this 77210693SMarco.Balboni@ARM.com * latency. 7739263Smrinmoy.ghosh@arm.com */ 7749288Sandreas.hansson@arm.com const Cycles responseLatency; 7754630SN/A 7764626SN/A /** The number of targets for each MSHR. */ 7774626SN/A const int numTarget; 7784626SN/A 7796122SSteve.Reinhardt@amd.com /** Do we forward snoops from mem side port through to cpu side port? */ 78011331Sandreas.hansson@arm.com bool forwardSnoops; 7814626SN/A 7822810SN/A /** 78312724Snikos.nikoleris@arm.com * Clusivity with respect to the upstream cache, determining if we 78412724Snikos.nikoleris@arm.com * fill into both this cache and the cache above on a miss. Note 78512724Snikos.nikoleris@arm.com * that we currently do not support strict clusivity policies. 78612724Snikos.nikoleris@arm.com */ 78712724Snikos.nikoleris@arm.com const Enums::Clusivity clusivity; 78812724Snikos.nikoleris@arm.com 78912724Snikos.nikoleris@arm.com /** 79010884Sandreas.hansson@arm.com * Is this cache read only, for example the instruction cache, or 79110884Sandreas.hansson@arm.com * table-walker cache. A cache that is read only should never see 79210884Sandreas.hansson@arm.com * any writes, and should never get any dirty data (and hence 79310884Sandreas.hansson@arm.com * never have to do any writebacks). 79410884Sandreas.hansson@arm.com */ 79510884Sandreas.hansson@arm.com const bool isReadOnly; 79610884Sandreas.hansson@arm.com 79710884Sandreas.hansson@arm.com /** 7982810SN/A * Bit vector of the blocking reasons for the access path. 7992810SN/A * @sa #BlockedCause 8002810SN/A */ 8012810SN/A uint8_t blocked; 8022810SN/A 8036122SSteve.Reinhardt@amd.com /** Increasing order number assigned to each incoming request. */ 8046122SSteve.Reinhardt@amd.com uint64_t order; 8056122SSteve.Reinhardt@amd.com 8062810SN/A /** Stores time the cache blocked for statistics. */ 8079288Sandreas.hansson@arm.com Cycles blockedCycle; 8082810SN/A 8094626SN/A /** Pointer to the MSHR that has no targets. */ 8104626SN/A MSHR *noTargetMSHR; 8112810SN/A 8122810SN/A /** The number of misses to trigger an exit event. */ 8132810SN/A Counter missCount; 8142810SN/A 8156122SSteve.Reinhardt@amd.com /** 8166122SSteve.Reinhardt@amd.com * The address range to which the cache responds on the CPU side. 8176122SSteve.Reinhardt@amd.com * Normally this is all possible memory addresses. */ 8189529Sandreas.hansson@arm.com const AddrRangeList addrRanges; 8196122SSteve.Reinhardt@amd.com 8208833Sdam.sunwoo@arm.com public: 8218833Sdam.sunwoo@arm.com /** System we are currently operating in. */ 8228833Sdam.sunwoo@arm.com System *system; 8236978SLisa.Hsu@amd.com 8242810SN/A // Statistics 8252810SN/A /** 8262810SN/A * @addtogroup CacheStatistics 8272810SN/A * @{ 8282810SN/A */ 8292810SN/A 83011483Snikos.nikoleris@arm.com /** Number of hits per thread for each type of command. 83111483Snikos.nikoleris@arm.com @sa Packet::Command */ 8325999Snate@binkert.org Stats::Vector hits[MemCmd::NUM_MEM_CMDS]; 8332810SN/A /** Number of hits for demand accesses. */ 8342810SN/A Stats::Formula demandHits; 8352810SN/A /** Number of hit for all accesses. */ 8362810SN/A Stats::Formula overallHits; 8372810SN/A 83811483Snikos.nikoleris@arm.com /** Number of misses per thread for each type of command. 83911483Snikos.nikoleris@arm.com @sa Packet::Command */ 8405999Snate@binkert.org Stats::Vector misses[MemCmd::NUM_MEM_CMDS]; 8412810SN/A /** Number of misses for demand accesses. */ 8422810SN/A Stats::Formula demandMisses; 8432810SN/A /** Number of misses for all accesses. */ 8442810SN/A Stats::Formula overallMisses; 8452810SN/A 8462810SN/A /** 8472810SN/A * Total number of cycles per thread/command spent waiting for a miss. 8482810SN/A * Used to calculate the average miss latency. 8492810SN/A */ 8505999Snate@binkert.org Stats::Vector missLatency[MemCmd::NUM_MEM_CMDS]; 8512810SN/A /** Total number of cycles spent waiting for demand misses. */ 8522810SN/A Stats::Formula demandMissLatency; 8532810SN/A /** Total number of cycles spent waiting for all misses. */ 8542810SN/A Stats::Formula overallMissLatency; 8552810SN/A 8562810SN/A /** The number of accesses per command and thread. */ 8574022SN/A Stats::Formula accesses[MemCmd::NUM_MEM_CMDS]; 8582810SN/A /** The number of demand accesses. */ 8592810SN/A Stats::Formula demandAccesses; 8602810SN/A /** The number of overall accesses. */ 8612810SN/A Stats::Formula overallAccesses; 8622810SN/A 8632810SN/A /** The miss rate per command and thread. */ 8644022SN/A Stats::Formula missRate[MemCmd::NUM_MEM_CMDS]; 8652810SN/A /** The miss rate of all demand accesses. */ 8662810SN/A Stats::Formula demandMissRate; 8672810SN/A /** The miss rate for all accesses. */ 8682810SN/A Stats::Formula overallMissRate; 8692810SN/A 8702810SN/A /** The average miss latency per command and thread. */ 8714022SN/A Stats::Formula avgMissLatency[MemCmd::NUM_MEM_CMDS]; 8722810SN/A /** The average miss latency for demand misses. */ 8732810SN/A Stats::Formula demandAvgMissLatency; 8742810SN/A /** The average miss latency for all misses. */ 8752810SN/A Stats::Formula overallAvgMissLatency; 8762810SN/A 8772810SN/A /** The total number of cycles blocked for each blocked cause. */ 8785999Snate@binkert.org Stats::Vector blocked_cycles; 8792810SN/A /** The number of times this cache blocked for each blocked cause. */ 8805999Snate@binkert.org Stats::Vector blocked_causes; 8812810SN/A 8822810SN/A /** The average number of cycles blocked for each blocked cause. */ 8832810SN/A Stats::Formula avg_blocked; 8842810SN/A 88511436SRekai.GonzalezAlberquilla@arm.com /** The number of times a HW-prefetched block is evicted w/o reference. */ 88611436SRekai.GonzalezAlberquilla@arm.com Stats::Scalar unusedPrefetches; 88711436SRekai.GonzalezAlberquilla@arm.com 8884626SN/A /** Number of blocks written back per thread. */ 8895999Snate@binkert.org Stats::Vector writebacks; 8904626SN/A 8914626SN/A /** Number of misses that hit in the MSHRs per command and thread. */ 8925999Snate@binkert.org Stats::Vector mshr_hits[MemCmd::NUM_MEM_CMDS]; 8934626SN/A /** Demand misses that hit in the MSHRs. */ 8944626SN/A Stats::Formula demandMshrHits; 8954626SN/A /** Total number of misses that hit in the MSHRs. */ 8964626SN/A Stats::Formula overallMshrHits; 8974626SN/A 8984626SN/A /** Number of misses that miss in the MSHRs, per command and thread. */ 8995999Snate@binkert.org Stats::Vector mshr_misses[MemCmd::NUM_MEM_CMDS]; 9004626SN/A /** Demand misses that miss in the MSHRs. */ 9014626SN/A Stats::Formula demandMshrMisses; 9024626SN/A /** Total number of misses that miss in the MSHRs. */ 9034626SN/A Stats::Formula overallMshrMisses; 9044626SN/A 9054626SN/A /** Number of misses that miss in the MSHRs, per command and thread. */ 9065999Snate@binkert.org Stats::Vector mshr_uncacheable[MemCmd::NUM_MEM_CMDS]; 9074626SN/A /** Total number of misses that miss in the MSHRs. */ 9084626SN/A Stats::Formula overallMshrUncacheable; 9094626SN/A 9104626SN/A /** Total cycle latency of each MSHR miss, per command and thread. */ 9115999Snate@binkert.org Stats::Vector mshr_miss_latency[MemCmd::NUM_MEM_CMDS]; 9124626SN/A /** Total cycle latency of demand MSHR misses. */ 9134626SN/A Stats::Formula demandMshrMissLatency; 9144626SN/A /** Total cycle latency of overall MSHR misses. */ 9154626SN/A Stats::Formula overallMshrMissLatency; 9164626SN/A 9174626SN/A /** Total cycle latency of each MSHR miss, per command and thread. */ 9185999Snate@binkert.org Stats::Vector mshr_uncacheable_lat[MemCmd::NUM_MEM_CMDS]; 9194626SN/A /** Total cycle latency of overall MSHR misses. */ 9204626SN/A Stats::Formula overallMshrUncacheableLatency; 9214626SN/A 9227461Snate@binkert.org#if 0 9234626SN/A /** The total number of MSHR accesses per command and thread. */ 9244626SN/A Stats::Formula mshrAccesses[MemCmd::NUM_MEM_CMDS]; 9254626SN/A /** The total number of demand MSHR accesses. */ 9264626SN/A Stats::Formula demandMshrAccesses; 9274626SN/A /** The total number of MSHR accesses. */ 9284626SN/A Stats::Formula overallMshrAccesses; 9297461Snate@binkert.org#endif 9304626SN/A 9314626SN/A /** The miss rate in the MSHRs pre command and thread. */ 9324626SN/A Stats::Formula mshrMissRate[MemCmd::NUM_MEM_CMDS]; 9334626SN/A /** The demand miss rate in the MSHRs. */ 9344626SN/A Stats::Formula demandMshrMissRate; 9354626SN/A /** The overall miss rate in the MSHRs. */ 9364626SN/A Stats::Formula overallMshrMissRate; 9374626SN/A 9384626SN/A /** The average latency of an MSHR miss, per command and thread. */ 9394626SN/A Stats::Formula avgMshrMissLatency[MemCmd::NUM_MEM_CMDS]; 9404626SN/A /** The average latency of a demand MSHR miss. */ 9414626SN/A Stats::Formula demandAvgMshrMissLatency; 9424626SN/A /** The average overall latency of an MSHR miss. */ 9434626SN/A Stats::Formula overallAvgMshrMissLatency; 9444626SN/A 9454626SN/A /** The average latency of an MSHR miss, per command and thread. */ 9464626SN/A Stats::Formula avgMshrUncacheableLatency[MemCmd::NUM_MEM_CMDS]; 9474626SN/A /** The average overall latency of an MSHR miss. */ 9484626SN/A Stats::Formula overallAvgMshrUncacheableLatency; 9494626SN/A 95012702Snikos.nikoleris@arm.com /** Number of replacements of valid blocks. */ 95112702Snikos.nikoleris@arm.com Stats::Scalar replacements; 95212702Snikos.nikoleris@arm.com 9532810SN/A /** 9542810SN/A * @} 9552810SN/A */ 9562810SN/A 9572810SN/A /** 9582810SN/A * Register stats for this object. 9592810SN/A */ 96012724Snikos.nikoleris@arm.com void regStats() override; 9612810SN/A 9622810SN/A public: 96311053Sandreas.hansson@arm.com BaseCache(const BaseCacheParams *p, unsigned blk_size); 96412724Snikos.nikoleris@arm.com ~BaseCache(); 9653606SN/A 96612724Snikos.nikoleris@arm.com void init() override; 9672858SN/A 96812724Snikos.nikoleris@arm.com BaseMasterPort &getMasterPort(const std::string &if_name, 96912724Snikos.nikoleris@arm.com PortID idx = InvalidPortID) override; 97012724Snikos.nikoleris@arm.com BaseSlavePort &getSlavePort(const std::string &if_name, 97112724Snikos.nikoleris@arm.com PortID idx = InvalidPortID) override; 9728922Swilliam.wang@arm.com 9732810SN/A /** 9742810SN/A * Query block size of a cache. 9752810SN/A * @return The block size 9762810SN/A */ 9776227Snate@binkert.org unsigned 9786227Snate@binkert.org getBlockSize() const 9792810SN/A { 9802810SN/A return blkSize; 9812810SN/A } 9822810SN/A 9838883SAli.Saidi@ARM.com const AddrRangeList &getAddrRanges() const { return addrRanges; } 9846122SSteve.Reinhardt@amd.com 98510942Sandreas.hansson@arm.com MSHR *allocateMissBuffer(PacketPtr pkt, Tick time, bool sched_send = true) 9864628SN/A { 98711892Snikos.nikoleris@arm.com MSHR *mshr = mshrQueue.allocate(pkt->getBlockAddr(blkSize), blkSize, 98811375Sandreas.hansson@arm.com pkt, time, order++, 98911375Sandreas.hansson@arm.com allocOnFill(pkt->cmd)); 99011375Sandreas.hansson@arm.com 99111375Sandreas.hansson@arm.com if (mshrQueue.isFull()) { 99211375Sandreas.hansson@arm.com setBlocked((BlockedCause)MSHRQueue_MSHRs); 99311375Sandreas.hansson@arm.com } 99411375Sandreas.hansson@arm.com 99511375Sandreas.hansson@arm.com if (sched_send) { 99611375Sandreas.hansson@arm.com // schedule the send 99711375Sandreas.hansson@arm.com schedMemSideSendEvent(time); 99811375Sandreas.hansson@arm.com } 99911375Sandreas.hansson@arm.com 100011375Sandreas.hansson@arm.com return mshr; 10014628SN/A } 10024628SN/A 100311375Sandreas.hansson@arm.com void allocateWriteBuffer(PacketPtr pkt, Tick time) 10044628SN/A { 100511191Sandreas.hansson@arm.com // should only see writes or clean evicts here 100611191Sandreas.hansson@arm.com assert(pkt->isWrite() || pkt->cmd == MemCmd::CleanEvict); 100711191Sandreas.hansson@arm.com 100811892Snikos.nikoleris@arm.com Addr blk_addr = pkt->getBlockAddr(blkSize); 100911375Sandreas.hansson@arm.com 101011375Sandreas.hansson@arm.com WriteQueueEntry *wq_entry = 101111375Sandreas.hansson@arm.com writeBuffer.findMatch(blk_addr, pkt->isSecure()); 101211375Sandreas.hansson@arm.com if (wq_entry && !wq_entry->inService) { 101311744Snikos.nikoleris@arm.com DPRINTF(Cache, "Potential to merge writeback %s", pkt->print()); 101411375Sandreas.hansson@arm.com } 101511375Sandreas.hansson@arm.com 101611375Sandreas.hansson@arm.com writeBuffer.allocate(blk_addr, blkSize, pkt, time, order++); 101711375Sandreas.hansson@arm.com 101811375Sandreas.hansson@arm.com if (writeBuffer.isFull()) { 101911375Sandreas.hansson@arm.com setBlocked((BlockedCause)MSHRQueue_WriteBuffer); 102011375Sandreas.hansson@arm.com } 102111375Sandreas.hansson@arm.com 102211375Sandreas.hansson@arm.com // schedule the send 102311375Sandreas.hansson@arm.com schedMemSideSendEvent(time); 10244628SN/A } 10254628SN/A 10262810SN/A /** 10272810SN/A * Returns true if the cache is blocked for accesses. 10282810SN/A */ 10299529Sandreas.hansson@arm.com bool isBlocked() const 10302810SN/A { 10312810SN/A return blocked != 0; 10322810SN/A } 10332810SN/A 10342810SN/A /** 10352810SN/A * Marks the access path of the cache as blocked for the given cause. This 10362810SN/A * also sets the blocked flag in the slave interface. 10372810SN/A * @param cause The reason for the cache blocking. 10382810SN/A */ 10392810SN/A void setBlocked(BlockedCause cause) 10402810SN/A { 10412810SN/A uint8_t flag = 1 << cause; 10422810SN/A if (blocked == 0) { 10432810SN/A blocked_causes[cause]++; 10449288Sandreas.hansson@arm.com blockedCycle = curCycle(); 104512724Snikos.nikoleris@arm.com cpuSidePort.setBlocked(); 10462810SN/A } 10474630SN/A blocked |= flag; 10484630SN/A DPRINTF(Cache,"Blocking for cause %d, mask=%d\n", cause, blocked); 10492810SN/A } 10502810SN/A 10512810SN/A /** 10522810SN/A * Marks the cache as unblocked for the given cause. This also clears the 10532810SN/A * blocked flags in the appropriate interfaces. 10542810SN/A * @param cause The newly unblocked cause. 10552810SN/A * @warning Calling this function can cause a blocked request on the bus to 10562810SN/A * access the cache. The cache must be in a state to handle that request. 10572810SN/A */ 10582810SN/A void clearBlocked(BlockedCause cause) 10592810SN/A { 10602810SN/A uint8_t flag = 1 << cause; 10614630SN/A blocked &= ~flag; 10624630SN/A DPRINTF(Cache,"Unblocking for cause %d, mask=%d\n", cause, blocked); 10634630SN/A if (blocked == 0) { 10649288Sandreas.hansson@arm.com blocked_cycles[cause] += curCycle() - blockedCycle; 106512724Snikos.nikoleris@arm.com cpuSidePort.clearBlocked(); 10662810SN/A } 10672810SN/A } 10682810SN/A 10692810SN/A /** 107010942Sandreas.hansson@arm.com * Schedule a send event for the memory-side port. If already 107110942Sandreas.hansson@arm.com * scheduled, this may reschedule the event at an earlier 107210942Sandreas.hansson@arm.com * time. When the specified time is reached, the port is free to 107310942Sandreas.hansson@arm.com * send either a response, a request, or a prefetch request. 107410942Sandreas.hansson@arm.com * 107510942Sandreas.hansson@arm.com * @param time The time when to attempt sending a packet. 10762810SN/A */ 107710942Sandreas.hansson@arm.com void schedMemSideSendEvent(Tick time) 10782810SN/A { 107912724Snikos.nikoleris@arm.com memSidePort.schedSendEvent(time); 10802811SN/A } 10813503SN/A 108212724Snikos.nikoleris@arm.com bool inCache(Addr addr, bool is_secure) const { 108312724Snikos.nikoleris@arm.com return tags->findBlock(addr, is_secure); 108412724Snikos.nikoleris@arm.com } 10854626SN/A 108612724Snikos.nikoleris@arm.com bool inMissQueue(Addr addr, bool is_secure) const { 108712724Snikos.nikoleris@arm.com return mshrQueue.findMatch(addr, is_secure); 108812724Snikos.nikoleris@arm.com } 10894626SN/A 10908833Sdam.sunwoo@arm.com void incMissCount(PacketPtr pkt) 10913503SN/A { 10928833Sdam.sunwoo@arm.com assert(pkt->req->masterId() < system->maxMasters()); 10938833Sdam.sunwoo@arm.com misses[pkt->cmdToIndex()][pkt->req->masterId()]++; 109410020Smatt.horsnell@ARM.com pkt->req->incAccessDepth(); 10954626SN/A if (missCount) { 10964626SN/A --missCount; 10974626SN/A if (missCount == 0) 10984626SN/A exitSimLoop("A cache reached the maximum miss count"); 10993503SN/A } 11003503SN/A } 11018833Sdam.sunwoo@arm.com void incHitCount(PacketPtr pkt) 11026978SLisa.Hsu@amd.com { 11038833Sdam.sunwoo@arm.com assert(pkt->req->masterId() < system->maxMasters()); 11048833Sdam.sunwoo@arm.com hits[pkt->cmdToIndex()][pkt->req->masterId()]++; 11056978SLisa.Hsu@amd.com 11066978SLisa.Hsu@amd.com } 11073503SN/A 110812724Snikos.nikoleris@arm.com /** 110912724Snikos.nikoleris@arm.com * Cache block visitor that writes back dirty cache blocks using 111012724Snikos.nikoleris@arm.com * functional writes. 111112724Snikos.nikoleris@arm.com * 111212724Snikos.nikoleris@arm.com * @return Always returns true. 111312724Snikos.nikoleris@arm.com */ 111412724Snikos.nikoleris@arm.com bool writebackVisitor(CacheBlk &blk); 111512724Snikos.nikoleris@arm.com 111612724Snikos.nikoleris@arm.com /** 111712724Snikos.nikoleris@arm.com * Cache block visitor that invalidates all blocks in the cache. 111812724Snikos.nikoleris@arm.com * 111912724Snikos.nikoleris@arm.com * @warn Dirty cache lines will not be written back to memory. 112012724Snikos.nikoleris@arm.com * 112112724Snikos.nikoleris@arm.com * @return Always returns true. 112212724Snikos.nikoleris@arm.com */ 112312724Snikos.nikoleris@arm.com bool invalidateVisitor(CacheBlk &blk); 112412724Snikos.nikoleris@arm.com 112512724Snikos.nikoleris@arm.com /** 112612724Snikos.nikoleris@arm.com * Take an MSHR, turn it into a suitable downstream packet, and 112712724Snikos.nikoleris@arm.com * send it out. This construct allows a queue entry to choose a suitable 112812724Snikos.nikoleris@arm.com * approach based on its type. 112912724Snikos.nikoleris@arm.com * 113012724Snikos.nikoleris@arm.com * @param mshr The MSHR to turn into a packet and send 113112724Snikos.nikoleris@arm.com * @return True if the port is waiting for a retry 113212724Snikos.nikoleris@arm.com */ 113312724Snikos.nikoleris@arm.com virtual bool sendMSHRQueuePacket(MSHR* mshr); 113412724Snikos.nikoleris@arm.com 113512724Snikos.nikoleris@arm.com /** 113612724Snikos.nikoleris@arm.com * Similar to sendMSHR, but for a write-queue entry 113712724Snikos.nikoleris@arm.com * instead. Create the packet, and send it, and if successful also 113812724Snikos.nikoleris@arm.com * mark the entry in service. 113912724Snikos.nikoleris@arm.com * 114012724Snikos.nikoleris@arm.com * @param wq_entry The write-queue entry to turn into a packet and send 114112724Snikos.nikoleris@arm.com * @return True if the port is waiting for a retry 114212724Snikos.nikoleris@arm.com */ 114312724Snikos.nikoleris@arm.com bool sendWriteQueuePacket(WriteQueueEntry* wq_entry); 114412724Snikos.nikoleris@arm.com 114512724Snikos.nikoleris@arm.com /** 114612724Snikos.nikoleris@arm.com * Serialize the state of the caches 114712724Snikos.nikoleris@arm.com * 114812724Snikos.nikoleris@arm.com * We currently don't support checkpointing cache state, so this panics. 114912724Snikos.nikoleris@arm.com */ 115012724Snikos.nikoleris@arm.com void serialize(CheckpointOut &cp) const override; 115112724Snikos.nikoleris@arm.com void unserialize(CheckpointIn &cp) override; 115212724Snikos.nikoleris@arm.com 115312724Snikos.nikoleris@arm.com}; 115412724Snikos.nikoleris@arm.com 115512724Snikos.nikoleris@arm.com/** 115612724Snikos.nikoleris@arm.com * Wrap a method and present it as a cache block visitor. 115712724Snikos.nikoleris@arm.com * 115812724Snikos.nikoleris@arm.com * For example the forEachBlk method in the tag arrays expects a 115912724Snikos.nikoleris@arm.com * callable object/function as their parameter. This class wraps a 116012724Snikos.nikoleris@arm.com * method in an object and presents callable object that adheres to 116112724Snikos.nikoleris@arm.com * the cache block visitor protocol. 116212724Snikos.nikoleris@arm.com */ 116312724Snikos.nikoleris@arm.comclass CacheBlkVisitorWrapper : public CacheBlkVisitor 116412724Snikos.nikoleris@arm.com{ 116512724Snikos.nikoleris@arm.com public: 116612724Snikos.nikoleris@arm.com typedef bool (BaseCache::*VisitorPtr)(CacheBlk &blk); 116712724Snikos.nikoleris@arm.com 116812724Snikos.nikoleris@arm.com CacheBlkVisitorWrapper(BaseCache &_cache, VisitorPtr _visitor) 116912724Snikos.nikoleris@arm.com : cache(_cache), visitor(_visitor) {} 117012724Snikos.nikoleris@arm.com 117112724Snikos.nikoleris@arm.com bool operator()(CacheBlk &blk) override { 117212724Snikos.nikoleris@arm.com return (cache.*visitor)(blk); 117312724Snikos.nikoleris@arm.com } 117412724Snikos.nikoleris@arm.com 117512724Snikos.nikoleris@arm.com private: 117612724Snikos.nikoleris@arm.com BaseCache &cache; 117712724Snikos.nikoleris@arm.com VisitorPtr visitor; 117812724Snikos.nikoleris@arm.com}; 117912724Snikos.nikoleris@arm.com 118012724Snikos.nikoleris@arm.com/** 118112724Snikos.nikoleris@arm.com * Cache block visitor that determines if there are dirty blocks in a 118212724Snikos.nikoleris@arm.com * cache. 118312724Snikos.nikoleris@arm.com * 118412724Snikos.nikoleris@arm.com * Use with the forEachBlk method in the tag array to determine if the 118512724Snikos.nikoleris@arm.com * array contains dirty blocks. 118612724Snikos.nikoleris@arm.com */ 118712724Snikos.nikoleris@arm.comclass CacheBlkIsDirtyVisitor : public CacheBlkVisitor 118812724Snikos.nikoleris@arm.com{ 118912724Snikos.nikoleris@arm.com public: 119012724Snikos.nikoleris@arm.com CacheBlkIsDirtyVisitor() 119112724Snikos.nikoleris@arm.com : _isDirty(false) {} 119212724Snikos.nikoleris@arm.com 119312724Snikos.nikoleris@arm.com bool operator()(CacheBlk &blk) override { 119412724Snikos.nikoleris@arm.com if (blk.isDirty()) { 119512724Snikos.nikoleris@arm.com _isDirty = true; 119612724Snikos.nikoleris@arm.com return false; 119712724Snikos.nikoleris@arm.com } else { 119812724Snikos.nikoleris@arm.com return true; 119912724Snikos.nikoleris@arm.com } 120012724Snikos.nikoleris@arm.com } 120112724Snikos.nikoleris@arm.com 120212724Snikos.nikoleris@arm.com /** 120312724Snikos.nikoleris@arm.com * Does the array contain a dirty line? 120412724Snikos.nikoleris@arm.com * 120512724Snikos.nikoleris@arm.com * @return true if yes, false otherwise. 120612724Snikos.nikoleris@arm.com */ 120712724Snikos.nikoleris@arm.com bool isDirty() const { return _isDirty; }; 120812724Snikos.nikoleris@arm.com 120912724Snikos.nikoleris@arm.com private: 121012724Snikos.nikoleris@arm.com bool _isDirty; 12112810SN/A}; 12122810SN/A 121311051Sandreas.hansson@arm.com#endif //__MEM_CACHE_BASE_HH__ 1214