base.hh revision 11893
12810SN/A/* 211375Sandreas.hansson@arm.com * Copyright (c) 2012-2013, 2015-2016 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 432810SN/A */ 442810SN/A 452810SN/A/** 462810SN/A * @file 472810SN/A * Declares a basic cache interface BaseCache. 482810SN/A */ 492810SN/A 5011051Sandreas.hansson@arm.com#ifndef __MEM_CACHE_BASE_HH__ 5111051Sandreas.hansson@arm.com#define __MEM_CACHE_BASE_HH__ 522810SN/A 537676Snate@binkert.org#include <algorithm> 547676Snate@binkert.org#include <list> 557676Snate@binkert.org#include <string> 562810SN/A#include <vector> 572810SN/A 582825SN/A#include "base/misc.hh" 592810SN/A#include "base/statistics.hh" 602810SN/A#include "base/trace.hh" 616215Snate@binkert.org#include "base/types.hh" 628232Snate@binkert.org#include "debug/Cache.hh" 638232Snate@binkert.org#include "debug/CachePort.hh" 645338Sstever@gmail.com#include "mem/cache/mshr_queue.hh" 6511375Sandreas.hansson@arm.com#include "mem/cache/write_queue.hh" 662810SN/A#include "mem/mem_object.hh" 672810SN/A#include "mem/packet.hh" 688914Sandreas.hansson@arm.com#include "mem/qport.hh" 698229Snate@binkert.org#include "mem/request.hh" 705034SN/A#include "params/BaseCache.hh" 712811SN/A#include "sim/eventq.hh" 728786Sgblack@eecs.umich.edu#include "sim/full_system.hh" 734626SN/A#include "sim/sim_exit.hh" 748833Sdam.sunwoo@arm.com#include "sim/system.hh" 752810SN/A 762810SN/A/** 772810SN/A * A basic cache interface. Implements some common functions for speed. 782810SN/A */ 792810SN/Aclass BaseCache : public MemObject 802810SN/A{ 8111375Sandreas.hansson@arm.com protected: 824628SN/A /** 834628SN/A * Indexes to enumerate the MSHR queues. 844628SN/A */ 854628SN/A enum MSHRQueueIndex { 864628SN/A MSHRQueue_MSHRs, 874628SN/A MSHRQueue_WriteBuffer 884628SN/A }; 894628SN/A 908737Skoansin.tan@gmail.com public: 914628SN/A /** 924628SN/A * Reasons for caches to be blocked. 934628SN/A */ 944628SN/A enum BlockedCause { 954628SN/A Blocked_NoMSHRs = MSHRQueue_MSHRs, 964628SN/A Blocked_NoWBBuffers = MSHRQueue_WriteBuffer, 974628SN/A Blocked_NoTargets, 984628SN/A NUM_BLOCKED_CAUSES 994628SN/A }; 1004628SN/A 1018737Skoansin.tan@gmail.com protected: 1024628SN/A 1038856Sandreas.hansson@arm.com /** 1048856Sandreas.hansson@arm.com * A cache master port is used for the memory-side port of the 1058856Sandreas.hansson@arm.com * cache, and in addition to the basic timing port that only sends 1068856Sandreas.hansson@arm.com * response packets through a transmit list, it also offers the 1078856Sandreas.hansson@arm.com * ability to schedule and send request packets (requests & 10810942Sandreas.hansson@arm.com * writebacks). The send event is scheduled through schedSendEvent, 1098856Sandreas.hansson@arm.com * and the sendDeferredPacket of the timing port is modified to 1108856Sandreas.hansson@arm.com * consider both the transmit list and the requests from the MSHR. 1118856Sandreas.hansson@arm.com */ 1128922Swilliam.wang@arm.com class CacheMasterPort : public QueuedMasterPort 1132810SN/A { 1148856Sandreas.hansson@arm.com 1152844SN/A public: 1168856Sandreas.hansson@arm.com 1178856Sandreas.hansson@arm.com /** 1188856Sandreas.hansson@arm.com * Schedule a send of a request packet (from the MSHR). Note 11910713Sandreas.hansson@arm.com * that we could already have a retry outstanding. 1208856Sandreas.hansson@arm.com */ 12110942Sandreas.hansson@arm.com void schedSendEvent(Tick time) 1228856Sandreas.hansson@arm.com { 12310942Sandreas.hansson@arm.com DPRINTF(CachePort, "Scheduling send event at %llu\n", time); 12410713Sandreas.hansson@arm.com reqQueue.schedSendEvent(time); 1258856Sandreas.hansson@arm.com } 1268856Sandreas.hansson@arm.com 1273738SN/A protected: 1284458SN/A 1298856Sandreas.hansson@arm.com CacheMasterPort(const std::string &_name, BaseCache *_cache, 13010713Sandreas.hansson@arm.com ReqPacketQueue &_reqQueue, 13110713Sandreas.hansson@arm.com SnoopRespPacketQueue &_snoopRespQueue) : 13210713Sandreas.hansson@arm.com QueuedMasterPort(_name, _cache, _reqQueue, _snoopRespQueue) 1338914Sandreas.hansson@arm.com { } 1342810SN/A 1358856Sandreas.hansson@arm.com /** 1368856Sandreas.hansson@arm.com * Memory-side port always snoops. 1378856Sandreas.hansson@arm.com * 1388914Sandreas.hansson@arm.com * @return always true 1398856Sandreas.hansson@arm.com */ 1408922Swilliam.wang@arm.com virtual bool isSnooping() const { return true; } 1418856Sandreas.hansson@arm.com }; 1423013SN/A 1438856Sandreas.hansson@arm.com /** 1448856Sandreas.hansson@arm.com * A cache slave port is used for the CPU-side port of the cache, 1458856Sandreas.hansson@arm.com * and it is basically a simple timing port that uses a transmit 1468856Sandreas.hansson@arm.com * list for responses to the CPU (or connected master). In 1478856Sandreas.hansson@arm.com * addition, it has the functionality to block the port for 1488856Sandreas.hansson@arm.com * incoming requests. If blocked, the port will issue a retry once 1498856Sandreas.hansson@arm.com * unblocked. 1508856Sandreas.hansson@arm.com */ 1518922Swilliam.wang@arm.com class CacheSlavePort : public QueuedSlavePort 1528856Sandreas.hansson@arm.com { 1535314SN/A 1542811SN/A public: 1558856Sandreas.hansson@arm.com 1568856Sandreas.hansson@arm.com /** Do not accept any new requests. */ 1572810SN/A void setBlocked(); 1582810SN/A 1598856Sandreas.hansson@arm.com /** Return to normal operation and accept new requests. */ 1602810SN/A void clearBlocked(); 1612810SN/A 16210345SCurtis.Dunham@arm.com bool isBlocked() const { return blocked; } 16310345SCurtis.Dunham@arm.com 1648856Sandreas.hansson@arm.com protected: 1658856Sandreas.hansson@arm.com 1668856Sandreas.hansson@arm.com CacheSlavePort(const std::string &_name, BaseCache *_cache, 1678856Sandreas.hansson@arm.com const std::string &_label); 1683606SN/A 1698914Sandreas.hansson@arm.com /** A normal packet queue used to store responses. */ 17010713Sandreas.hansson@arm.com RespPacketQueue queue; 1718914Sandreas.hansson@arm.com 1722810SN/A bool blocked; 1732810SN/A 1742897SN/A bool mustSendRetry; 1752897SN/A 1768856Sandreas.hansson@arm.com private: 1774458SN/A 17810344Sandreas.hansson@arm.com void processSendRetry(); 17910344Sandreas.hansson@arm.com 18010344Sandreas.hansson@arm.com EventWrapper<CacheSlavePort, 18110344Sandreas.hansson@arm.com &CacheSlavePort::processSendRetry> sendRetryEvent; 1828856Sandreas.hansson@arm.com 1832811SN/A }; 1842810SN/A 1858856Sandreas.hansson@arm.com CacheSlavePort *cpuSidePort; 1868856Sandreas.hansson@arm.com CacheMasterPort *memSidePort; 1873338SN/A 1884626SN/A protected: 1894626SN/A 1904626SN/A /** Miss status registers */ 1914626SN/A MSHRQueue mshrQueue; 1924626SN/A 1934626SN/A /** Write/writeback buffer */ 19411375Sandreas.hansson@arm.com WriteQueue writeBuffer; 1954626SN/A 19610693SMarco.Balboni@ARM.com /** 19711375Sandreas.hansson@arm.com * Mark a request as in service (sent downstream in the memory 19811375Sandreas.hansson@arm.com * system), effectively making this MSHR the ordering point. 19910693SMarco.Balboni@ARM.com */ 20011375Sandreas.hansson@arm.com void markInService(MSHR *mshr, bool pending_modified_resp) 2014628SN/A { 20211375Sandreas.hansson@arm.com bool wasFull = mshrQueue.isFull(); 20311375Sandreas.hansson@arm.com mshrQueue.markInService(mshr, pending_modified_resp); 20410764Sandreas.hansson@arm.com 20511375Sandreas.hansson@arm.com if (wasFull && !mshrQueue.isFull()) { 20611375Sandreas.hansson@arm.com clearBlocked(Blocked_NoMSHRs); 2074628SN/A } 2084628SN/A } 2094628SN/A 21011375Sandreas.hansson@arm.com void markInService(WriteQueueEntry *entry) 2114628SN/A { 21211375Sandreas.hansson@arm.com bool wasFull = writeBuffer.isFull(); 21311375Sandreas.hansson@arm.com writeBuffer.markInService(entry); 21411375Sandreas.hansson@arm.com 21511375Sandreas.hansson@arm.com if (wasFull && !writeBuffer.isFull()) { 21611375Sandreas.hansson@arm.com clearBlocked(Blocked_NoWBBuffers); 2174628SN/A } 2184628SN/A } 2194628SN/A 2209347SAndreas.Sandberg@arm.com /** 22111197Sandreas.hansson@arm.com * Determine if we should allocate on a fill or not. 22211197Sandreas.hansson@arm.com * 22311197Sandreas.hansson@arm.com * @param cmd Packet command being added as an MSHR target 22411197Sandreas.hansson@arm.com * 22511197Sandreas.hansson@arm.com * @return Whether we should allocate on a fill or not 22611197Sandreas.hansson@arm.com */ 22711197Sandreas.hansson@arm.com virtual bool allocOnFill(MemCmd cmd) const = 0; 22811197Sandreas.hansson@arm.com 22911197Sandreas.hansson@arm.com /** 2309347SAndreas.Sandberg@arm.com * Write back dirty blocks in the cache using functional accesses. 2319347SAndreas.Sandberg@arm.com */ 2329347SAndreas.Sandberg@arm.com virtual void memWriteback() = 0; 2339347SAndreas.Sandberg@arm.com /** 2349347SAndreas.Sandberg@arm.com * Invalidates all blocks in the cache. 2359347SAndreas.Sandberg@arm.com * 2369347SAndreas.Sandberg@arm.com * @warn Dirty cache lines will not be written back to 2379347SAndreas.Sandberg@arm.com * memory. Make sure to call functionalWriteback() first if you 2389347SAndreas.Sandberg@arm.com * want the to write them to memory. 2399347SAndreas.Sandberg@arm.com */ 2409347SAndreas.Sandberg@arm.com virtual void memInvalidate() = 0; 2419347SAndreas.Sandberg@arm.com /** 2429347SAndreas.Sandberg@arm.com * Determine if there are any dirty blocks in the cache. 2439347SAndreas.Sandberg@arm.com * 2449347SAndreas.Sandberg@arm.com * \return true if at least one block is dirty, false otherwise. 2459347SAndreas.Sandberg@arm.com */ 2469347SAndreas.Sandberg@arm.com virtual bool isDirty() const = 0; 2479347SAndreas.Sandberg@arm.com 24810821Sandreas.hansson@arm.com /** 24910821Sandreas.hansson@arm.com * Determine if an address is in the ranges covered by this 25010821Sandreas.hansson@arm.com * cache. This is useful to filter snoops. 25110821Sandreas.hansson@arm.com * 25210821Sandreas.hansson@arm.com * @param addr Address to check against 25310821Sandreas.hansson@arm.com * 25410821Sandreas.hansson@arm.com * @return If the address in question is in range 25510821Sandreas.hansson@arm.com */ 25610821Sandreas.hansson@arm.com bool inRange(Addr addr) const; 25710821Sandreas.hansson@arm.com 2584626SN/A /** Block size of this cache */ 2596227Snate@binkert.org const unsigned blkSize; 2604626SN/A 2614630SN/A /** 26210693SMarco.Balboni@ARM.com * The latency of tag lookup of a cache. It occurs when there is 26310693SMarco.Balboni@ARM.com * an access to the cache. 2644630SN/A */ 26510693SMarco.Balboni@ARM.com const Cycles lookupLatency; 2669263Smrinmoy.ghosh@arm.com 2679263Smrinmoy.ghosh@arm.com /** 26811722Ssophiane.senni@gmail.com * The latency of data access of a cache. It occurs when there is 26911722Ssophiane.senni@gmail.com * an access to the cache. 27011722Ssophiane.senni@gmail.com */ 27111722Ssophiane.senni@gmail.com const Cycles dataLatency; 27211722Ssophiane.senni@gmail.com 27311722Ssophiane.senni@gmail.com /** 27410693SMarco.Balboni@ARM.com * This is the forward latency of the cache. It occurs when there 27510693SMarco.Balboni@ARM.com * is a cache miss and a request is forwarded downstream, in 27610693SMarco.Balboni@ARM.com * particular an outbound miss. 27710693SMarco.Balboni@ARM.com */ 27810693SMarco.Balboni@ARM.com const Cycles forwardLatency; 27910693SMarco.Balboni@ARM.com 28010693SMarco.Balboni@ARM.com /** The latency to fill a cache block */ 28110693SMarco.Balboni@ARM.com const Cycles fillLatency; 28210693SMarco.Balboni@ARM.com 28310693SMarco.Balboni@ARM.com /** 28410693SMarco.Balboni@ARM.com * The latency of sending reponse to its upper level cache/core on 28510693SMarco.Balboni@ARM.com * a linefill. The responseLatency parameter captures this 28610693SMarco.Balboni@ARM.com * latency. 2879263Smrinmoy.ghosh@arm.com */ 2889288Sandreas.hansson@arm.com const Cycles responseLatency; 2894630SN/A 2904626SN/A /** The number of targets for each MSHR. */ 2914626SN/A const int numTarget; 2924626SN/A 2936122SSteve.Reinhardt@amd.com /** Do we forward snoops from mem side port through to cpu side port? */ 29411331Sandreas.hansson@arm.com bool forwardSnoops; 2954626SN/A 2962810SN/A /** 29710884Sandreas.hansson@arm.com * Is this cache read only, for example the instruction cache, or 29810884Sandreas.hansson@arm.com * table-walker cache. A cache that is read only should never see 29910884Sandreas.hansson@arm.com * any writes, and should never get any dirty data (and hence 30010884Sandreas.hansson@arm.com * never have to do any writebacks). 30110884Sandreas.hansson@arm.com */ 30210884Sandreas.hansson@arm.com const bool isReadOnly; 30310884Sandreas.hansson@arm.com 30410884Sandreas.hansson@arm.com /** 3052810SN/A * Bit vector of the blocking reasons for the access path. 3062810SN/A * @sa #BlockedCause 3072810SN/A */ 3082810SN/A uint8_t blocked; 3092810SN/A 3106122SSteve.Reinhardt@amd.com /** Increasing order number assigned to each incoming request. */ 3116122SSteve.Reinhardt@amd.com uint64_t order; 3126122SSteve.Reinhardt@amd.com 3132810SN/A /** Stores time the cache blocked for statistics. */ 3149288Sandreas.hansson@arm.com Cycles blockedCycle; 3152810SN/A 3164626SN/A /** Pointer to the MSHR that has no targets. */ 3174626SN/A MSHR *noTargetMSHR; 3182810SN/A 3192810SN/A /** The number of misses to trigger an exit event. */ 3202810SN/A Counter missCount; 3212810SN/A 3226122SSteve.Reinhardt@amd.com /** 3236122SSteve.Reinhardt@amd.com * The address range to which the cache responds on the CPU side. 3246122SSteve.Reinhardt@amd.com * Normally this is all possible memory addresses. */ 3259529Sandreas.hansson@arm.com const AddrRangeList addrRanges; 3266122SSteve.Reinhardt@amd.com 3278833Sdam.sunwoo@arm.com public: 3288833Sdam.sunwoo@arm.com /** System we are currently operating in. */ 3298833Sdam.sunwoo@arm.com System *system; 3306978SLisa.Hsu@amd.com 3312810SN/A // Statistics 3322810SN/A /** 3332810SN/A * @addtogroup CacheStatistics 3342810SN/A * @{ 3352810SN/A */ 3362810SN/A 33711483Snikos.nikoleris@arm.com /** Number of hits per thread for each type of command. 33811483Snikos.nikoleris@arm.com @sa Packet::Command */ 3395999Snate@binkert.org Stats::Vector hits[MemCmd::NUM_MEM_CMDS]; 3402810SN/A /** Number of hits for demand accesses. */ 3412810SN/A Stats::Formula demandHits; 3422810SN/A /** Number of hit for all accesses. */ 3432810SN/A Stats::Formula overallHits; 3442810SN/A 34511483Snikos.nikoleris@arm.com /** Number of misses per thread for each type of command. 34611483Snikos.nikoleris@arm.com @sa Packet::Command */ 3475999Snate@binkert.org Stats::Vector misses[MemCmd::NUM_MEM_CMDS]; 3482810SN/A /** Number of misses for demand accesses. */ 3492810SN/A Stats::Formula demandMisses; 3502810SN/A /** Number of misses for all accesses. */ 3512810SN/A Stats::Formula overallMisses; 3522810SN/A 3532810SN/A /** 3542810SN/A * Total number of cycles per thread/command spent waiting for a miss. 3552810SN/A * Used to calculate the average miss latency. 3562810SN/A */ 3575999Snate@binkert.org Stats::Vector missLatency[MemCmd::NUM_MEM_CMDS]; 3582810SN/A /** Total number of cycles spent waiting for demand misses. */ 3592810SN/A Stats::Formula demandMissLatency; 3602810SN/A /** Total number of cycles spent waiting for all misses. */ 3612810SN/A Stats::Formula overallMissLatency; 3622810SN/A 3632810SN/A /** The number of accesses per command and thread. */ 3644022SN/A Stats::Formula accesses[MemCmd::NUM_MEM_CMDS]; 3652810SN/A /** The number of demand accesses. */ 3662810SN/A Stats::Formula demandAccesses; 3672810SN/A /** The number of overall accesses. */ 3682810SN/A Stats::Formula overallAccesses; 3692810SN/A 3702810SN/A /** The miss rate per command and thread. */ 3714022SN/A Stats::Formula missRate[MemCmd::NUM_MEM_CMDS]; 3722810SN/A /** The miss rate of all demand accesses. */ 3732810SN/A Stats::Formula demandMissRate; 3742810SN/A /** The miss rate for all accesses. */ 3752810SN/A Stats::Formula overallMissRate; 3762810SN/A 3772810SN/A /** The average miss latency per command and thread. */ 3784022SN/A Stats::Formula avgMissLatency[MemCmd::NUM_MEM_CMDS]; 3792810SN/A /** The average miss latency for demand misses. */ 3802810SN/A Stats::Formula demandAvgMissLatency; 3812810SN/A /** The average miss latency for all misses. */ 3822810SN/A Stats::Formula overallAvgMissLatency; 3832810SN/A 3842810SN/A /** The total number of cycles blocked for each blocked cause. */ 3855999Snate@binkert.org Stats::Vector blocked_cycles; 3862810SN/A /** The number of times this cache blocked for each blocked cause. */ 3875999Snate@binkert.org Stats::Vector blocked_causes; 3882810SN/A 3892810SN/A /** The average number of cycles blocked for each blocked cause. */ 3902810SN/A Stats::Formula avg_blocked; 3912810SN/A 39211436SRekai.GonzalezAlberquilla@arm.com /** The number of times a HW-prefetched block is evicted w/o reference. */ 39311436SRekai.GonzalezAlberquilla@arm.com Stats::Scalar unusedPrefetches; 39411436SRekai.GonzalezAlberquilla@arm.com 3954626SN/A /** Number of blocks written back per thread. */ 3965999Snate@binkert.org Stats::Vector writebacks; 3974626SN/A 3984626SN/A /** Number of misses that hit in the MSHRs per command and thread. */ 3995999Snate@binkert.org Stats::Vector mshr_hits[MemCmd::NUM_MEM_CMDS]; 4004626SN/A /** Demand misses that hit in the MSHRs. */ 4014626SN/A Stats::Formula demandMshrHits; 4024626SN/A /** Total number of misses that hit in the MSHRs. */ 4034626SN/A Stats::Formula overallMshrHits; 4044626SN/A 4054626SN/A /** Number of misses that miss in the MSHRs, per command and thread. */ 4065999Snate@binkert.org Stats::Vector mshr_misses[MemCmd::NUM_MEM_CMDS]; 4074626SN/A /** Demand misses that miss in the MSHRs. */ 4084626SN/A Stats::Formula demandMshrMisses; 4094626SN/A /** Total number of misses that miss in the MSHRs. */ 4104626SN/A Stats::Formula overallMshrMisses; 4114626SN/A 4124626SN/A /** Number of misses that miss in the MSHRs, per command and thread. */ 4135999Snate@binkert.org Stats::Vector mshr_uncacheable[MemCmd::NUM_MEM_CMDS]; 4144626SN/A /** Total number of misses that miss in the MSHRs. */ 4154626SN/A Stats::Formula overallMshrUncacheable; 4164626SN/A 4174626SN/A /** Total cycle latency of each MSHR miss, per command and thread. */ 4185999Snate@binkert.org Stats::Vector mshr_miss_latency[MemCmd::NUM_MEM_CMDS]; 4194626SN/A /** Total cycle latency of demand MSHR misses. */ 4204626SN/A Stats::Formula demandMshrMissLatency; 4214626SN/A /** Total cycle latency of overall MSHR misses. */ 4224626SN/A Stats::Formula overallMshrMissLatency; 4234626SN/A 4244626SN/A /** Total cycle latency of each MSHR miss, per command and thread. */ 4255999Snate@binkert.org Stats::Vector mshr_uncacheable_lat[MemCmd::NUM_MEM_CMDS]; 4264626SN/A /** Total cycle latency of overall MSHR misses. */ 4274626SN/A Stats::Formula overallMshrUncacheableLatency; 4284626SN/A 4297461Snate@binkert.org#if 0 4304626SN/A /** The total number of MSHR accesses per command and thread. */ 4314626SN/A Stats::Formula mshrAccesses[MemCmd::NUM_MEM_CMDS]; 4324626SN/A /** The total number of demand MSHR accesses. */ 4334626SN/A Stats::Formula demandMshrAccesses; 4344626SN/A /** The total number of MSHR accesses. */ 4354626SN/A Stats::Formula overallMshrAccesses; 4367461Snate@binkert.org#endif 4374626SN/A 4384626SN/A /** The miss rate in the MSHRs pre command and thread. */ 4394626SN/A Stats::Formula mshrMissRate[MemCmd::NUM_MEM_CMDS]; 4404626SN/A /** The demand miss rate in the MSHRs. */ 4414626SN/A Stats::Formula demandMshrMissRate; 4424626SN/A /** The overall miss rate in the MSHRs. */ 4434626SN/A Stats::Formula overallMshrMissRate; 4444626SN/A 4454626SN/A /** The average latency of an MSHR miss, per command and thread. */ 4464626SN/A Stats::Formula avgMshrMissLatency[MemCmd::NUM_MEM_CMDS]; 4474626SN/A /** The average latency of a demand MSHR miss. */ 4484626SN/A Stats::Formula demandAvgMshrMissLatency; 4494626SN/A /** The average overall latency of an MSHR miss. */ 4504626SN/A Stats::Formula overallAvgMshrMissLatency; 4514626SN/A 4524626SN/A /** The average latency of an MSHR miss, per command and thread. */ 4534626SN/A Stats::Formula avgMshrUncacheableLatency[MemCmd::NUM_MEM_CMDS]; 4544626SN/A /** The average overall latency of an MSHR miss. */ 4554626SN/A Stats::Formula overallAvgMshrUncacheableLatency; 4564626SN/A 4572810SN/A /** 4582810SN/A * @} 4592810SN/A */ 4602810SN/A 4612810SN/A /** 4622810SN/A * Register stats for this object. 4632810SN/A */ 4642810SN/A virtual void regStats(); 4652810SN/A 4662810SN/A public: 46711053Sandreas.hansson@arm.com BaseCache(const BaseCacheParams *p, unsigned blk_size); 4685034SN/A ~BaseCache() {} 4693606SN/A 4702858SN/A virtual void init(); 4712858SN/A 4729294Sandreas.hansson@arm.com virtual BaseMasterPort &getMasterPort(const std::string &if_name, 4739294Sandreas.hansson@arm.com PortID idx = InvalidPortID); 4749294Sandreas.hansson@arm.com virtual BaseSlavePort &getSlavePort(const std::string &if_name, 4759294Sandreas.hansson@arm.com PortID idx = InvalidPortID); 4768922Swilliam.wang@arm.com 4772810SN/A /** 4782810SN/A * Query block size of a cache. 4792810SN/A * @return The block size 4802810SN/A */ 4816227Snate@binkert.org unsigned 4826227Snate@binkert.org getBlockSize() const 4832810SN/A { 4842810SN/A return blkSize; 4852810SN/A } 4862810SN/A 4878883SAli.Saidi@ARM.com const AddrRangeList &getAddrRanges() const { return addrRanges; } 4886122SSteve.Reinhardt@amd.com 48910942Sandreas.hansson@arm.com MSHR *allocateMissBuffer(PacketPtr pkt, Tick time, bool sched_send = true) 4904628SN/A { 49111892Snikos.nikoleris@arm.com MSHR *mshr = mshrQueue.allocate(pkt->getBlockAddr(blkSize), blkSize, 49211375Sandreas.hansson@arm.com pkt, time, order++, 49311375Sandreas.hansson@arm.com allocOnFill(pkt->cmd)); 49411375Sandreas.hansson@arm.com 49511375Sandreas.hansson@arm.com if (mshrQueue.isFull()) { 49611375Sandreas.hansson@arm.com setBlocked((BlockedCause)MSHRQueue_MSHRs); 49711375Sandreas.hansson@arm.com } 49811375Sandreas.hansson@arm.com 49911375Sandreas.hansson@arm.com if (sched_send) { 50011375Sandreas.hansson@arm.com // schedule the send 50111375Sandreas.hansson@arm.com schedMemSideSendEvent(time); 50211375Sandreas.hansson@arm.com } 50311375Sandreas.hansson@arm.com 50411375Sandreas.hansson@arm.com return mshr; 5054628SN/A } 5064628SN/A 50711375Sandreas.hansson@arm.com void allocateWriteBuffer(PacketPtr pkt, Tick time) 5084628SN/A { 50911191Sandreas.hansson@arm.com // should only see writes or clean evicts here 51011191Sandreas.hansson@arm.com assert(pkt->isWrite() || pkt->cmd == MemCmd::CleanEvict); 51111191Sandreas.hansson@arm.com 51211892Snikos.nikoleris@arm.com Addr blk_addr = pkt->getBlockAddr(blkSize); 51311375Sandreas.hansson@arm.com 51411375Sandreas.hansson@arm.com WriteQueueEntry *wq_entry = 51511375Sandreas.hansson@arm.com writeBuffer.findMatch(blk_addr, pkt->isSecure()); 51611375Sandreas.hansson@arm.com if (wq_entry && !wq_entry->inService) { 51711744Snikos.nikoleris@arm.com DPRINTF(Cache, "Potential to merge writeback %s", pkt->print()); 51811375Sandreas.hansson@arm.com } 51911375Sandreas.hansson@arm.com 52011375Sandreas.hansson@arm.com writeBuffer.allocate(blk_addr, blkSize, pkt, time, order++); 52111375Sandreas.hansson@arm.com 52211375Sandreas.hansson@arm.com if (writeBuffer.isFull()) { 52311375Sandreas.hansson@arm.com setBlocked((BlockedCause)MSHRQueue_WriteBuffer); 52411375Sandreas.hansson@arm.com } 52511375Sandreas.hansson@arm.com 52611375Sandreas.hansson@arm.com // schedule the send 52711375Sandreas.hansson@arm.com schedMemSideSendEvent(time); 5284628SN/A } 5294628SN/A 5302810SN/A /** 5312810SN/A * Returns true if the cache is blocked for accesses. 5322810SN/A */ 5339529Sandreas.hansson@arm.com bool isBlocked() const 5342810SN/A { 5352810SN/A return blocked != 0; 5362810SN/A } 5372810SN/A 5382810SN/A /** 5392810SN/A * Marks the access path of the cache as blocked for the given cause. This 5402810SN/A * also sets the blocked flag in the slave interface. 5412810SN/A * @param cause The reason for the cache blocking. 5422810SN/A */ 5432810SN/A void setBlocked(BlockedCause cause) 5442810SN/A { 5452810SN/A uint8_t flag = 1 << cause; 5462810SN/A if (blocked == 0) { 5472810SN/A blocked_causes[cause]++; 5489288Sandreas.hansson@arm.com blockedCycle = curCycle(); 5494630SN/A cpuSidePort->setBlocked(); 5502810SN/A } 5514630SN/A blocked |= flag; 5524630SN/A DPRINTF(Cache,"Blocking for cause %d, mask=%d\n", cause, blocked); 5532810SN/A } 5542810SN/A 5552810SN/A /** 5562810SN/A * Marks the cache as unblocked for the given cause. This also clears the 5572810SN/A * blocked flags in the appropriate interfaces. 5582810SN/A * @param cause The newly unblocked cause. 5592810SN/A * @warning Calling this function can cause a blocked request on the bus to 5602810SN/A * access the cache. The cache must be in a state to handle that request. 5612810SN/A */ 5622810SN/A void clearBlocked(BlockedCause cause) 5632810SN/A { 5642810SN/A uint8_t flag = 1 << cause; 5654630SN/A blocked &= ~flag; 5664630SN/A DPRINTF(Cache,"Unblocking for cause %d, mask=%d\n", cause, blocked); 5674630SN/A if (blocked == 0) { 5689288Sandreas.hansson@arm.com blocked_cycles[cause] += curCycle() - blockedCycle; 5694630SN/A cpuSidePort->clearBlocked(); 5702810SN/A } 5712810SN/A } 5722810SN/A 5732810SN/A /** 57410942Sandreas.hansson@arm.com * Schedule a send event for the memory-side port. If already 57510942Sandreas.hansson@arm.com * scheduled, this may reschedule the event at an earlier 57610942Sandreas.hansson@arm.com * time. When the specified time is reached, the port is free to 57710942Sandreas.hansson@arm.com * send either a response, a request, or a prefetch request. 57810942Sandreas.hansson@arm.com * 57910942Sandreas.hansson@arm.com * @param time The time when to attempt sending a packet. 5802810SN/A */ 58110942Sandreas.hansson@arm.com void schedMemSideSendEvent(Tick time) 5822810SN/A { 58310942Sandreas.hansson@arm.com memSidePort->schedSendEvent(time); 5842811SN/A } 5853503SN/A 58610028SGiacomo.Gabrielli@arm.com virtual bool inCache(Addr addr, bool is_secure) const = 0; 5874626SN/A 58810028SGiacomo.Gabrielli@arm.com virtual bool inMissQueue(Addr addr, bool is_secure) const = 0; 5894626SN/A 5908833Sdam.sunwoo@arm.com void incMissCount(PacketPtr pkt) 5913503SN/A { 5928833Sdam.sunwoo@arm.com assert(pkt->req->masterId() < system->maxMasters()); 5938833Sdam.sunwoo@arm.com misses[pkt->cmdToIndex()][pkt->req->masterId()]++; 59410020Smatt.horsnell@ARM.com pkt->req->incAccessDepth(); 5954626SN/A if (missCount) { 5964626SN/A --missCount; 5974626SN/A if (missCount == 0) 5984626SN/A exitSimLoop("A cache reached the maximum miss count"); 5993503SN/A } 6003503SN/A } 6018833Sdam.sunwoo@arm.com void incHitCount(PacketPtr pkt) 6026978SLisa.Hsu@amd.com { 6038833Sdam.sunwoo@arm.com assert(pkt->req->masterId() < system->maxMasters()); 6048833Sdam.sunwoo@arm.com hits[pkt->cmdToIndex()][pkt->req->masterId()]++; 6056978SLisa.Hsu@amd.com 6066978SLisa.Hsu@amd.com } 6073503SN/A 6082810SN/A}; 6092810SN/A 61011051Sandreas.hansson@arm.com#endif //__MEM_CACHE_BASE_HH__ 611