cache.hh revision 4672
12810Srdreslin@umich.edu/*
29529Sandreas.hansson@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
38702Sandreas.hansson@arm.com * All rights reserved.
48702Sandreas.hansson@arm.com *
58702Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68702Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78702Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88702Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98702Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108702Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118702Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128702Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138702Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
142810Srdreslin@umich.edu * this software without specific prior written permission.
152810Srdreslin@umich.edu *
162810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810Srdreslin@umich.edu *
282810Srdreslin@umich.edu * Authors: Erik Hallnor
292810Srdreslin@umich.edu *          Dave Greene
302810Srdreslin@umich.edu *          Steve Reinhardt
312810Srdreslin@umich.edu *          Ron Dreslinski
322810Srdreslin@umich.edu */
332810Srdreslin@umich.edu
342810Srdreslin@umich.edu/**
352810Srdreslin@umich.edu * @file
362810Srdreslin@umich.edu * Describes a cache based on template policies.
372810Srdreslin@umich.edu */
382810Srdreslin@umich.edu
392810Srdreslin@umich.edu#ifndef __CACHE_HH__
402810Srdreslin@umich.edu#define __CACHE_HH__
412810Srdreslin@umich.edu
422810Srdreslin@umich.edu#include "base/misc.hh" // fatal, panic, and warn
434458Sstever@eecs.umich.edu
448856Sandreas.hansson@arm.com#include "mem/cache/base_cache.hh"
452810Srdreslin@umich.edu#include "mem/cache/cache_blk.hh"
462810Srdreslin@umich.edu#include "mem/cache/miss/mshr.hh"
472810Srdreslin@umich.edu
482810Srdreslin@umich.edu#include "sim/eventq.hh"
492810Srdreslin@umich.edu
502810Srdreslin@umich.edu//Forward decleration
512810Srdreslin@umich.educlass BasePrefetcher;
522810Srdreslin@umich.edu
532810Srdreslin@umich.edu/**
542810Srdreslin@umich.edu * A template-policy based cache. The behavior of the cache can be altered by
552810Srdreslin@umich.edu * supplying different template policies. TagStore handles all tag and data
565338Sstever@gmail.com * storage @sa TagStore.
575338Sstever@gmail.com */
585338Sstever@gmail.comtemplate <class TagStore>
594458Sstever@eecs.umich.educlass Cache : public BaseCache
604458Sstever@eecs.umich.edu{
612813Srdreslin@umich.edu  public:
623861Sstever@eecs.umich.edu    /** Define the type of cache block to use. */
632810Srdreslin@umich.edu    typedef typename TagStore::BlkType BlkType;
642810Srdreslin@umich.edu    /** A typedef for a list of BlkType pointers. */
652810Srdreslin@umich.edu    typedef typename TagStore::BlkList BlkList;
662810Srdreslin@umich.edu
679264Sdjordje.kovacevic@arm.com    bool prefetchAccess;
682810Srdreslin@umich.edu
694672Sstever@eecs.umich.edu  protected:
702810Srdreslin@umich.edu
712810Srdreslin@umich.edu    class CpuSidePort : public CachePort
722810Srdreslin@umich.edu    {
732810Srdreslin@umich.edu      public:
742810Srdreslin@umich.edu        CpuSidePort(const std::string &_name,
753860Sstever@eecs.umich.edu                    Cache<TagStore> *_cache);
763860Sstever@eecs.umich.edu
772810Srdreslin@umich.edu        // BaseCache::CachePort just has a BaseCache *; this function
782810Srdreslin@umich.edu        // lets us get back the type info we lost when we stored the
799347SAndreas.Sandberg@arm.com        // cache pointer there.
802810Srdreslin@umich.edu        Cache<TagStore> *myCache() {
818856Sandreas.hansson@arm.com            return static_cast<Cache<TagStore> *>(cache);
828856Sandreas.hansson@arm.com        }
838856Sandreas.hansson@arm.com
848856Sandreas.hansson@arm.com        virtual void getDeviceAddressRanges(AddrRangeList &resp,
858856Sandreas.hansson@arm.com                                            bool &snoop);
863738Sstever@eecs.umich.edu
878856Sandreas.hansson@arm.com        virtual bool recvTiming(PacketPtr pkt);
883738Sstever@eecs.umich.edu
898856Sandreas.hansson@arm.com        virtual Tick recvAtomic(PacketPtr pkt);
908856Sandreas.hansson@arm.com
913738Sstever@eecs.umich.edu        virtual void recvFunctional(PacketPtr pkt);
928856Sandreas.hansson@arm.com    };
934478Sstever@eecs.umich.edu
948975Sandreas.hansson@arm.com    class MemSidePort : public CachePort
958948Sandreas.hansson@arm.com    {
968975Sandreas.hansson@arm.com      public:
973738Sstever@eecs.umich.edu        MemSidePort(const std::string &_name,
983738Sstever@eecs.umich.edu                    Cache<TagStore> *_cache);
993738Sstever@eecs.umich.edu
1003738Sstever@eecs.umich.edu        // BaseCache::CachePort just has a BaseCache *; this function
1018856Sandreas.hansson@arm.com        // lets us get back the type info we lost when we stored the
1028856Sandreas.hansson@arm.com        // cache pointer there.
1038856Sandreas.hansson@arm.com        Cache<TagStore> *myCache() {
1048856Sandreas.hansson@arm.com            return static_cast<Cache<TagStore> *>(cache);
1059090Sandreas.hansson@arm.com        }
1068856Sandreas.hansson@arm.com
1078856Sandreas.hansson@arm.com        void sendPacket();
1088856Sandreas.hansson@arm.com
1098856Sandreas.hansson@arm.com        void processSendEvent();
1108856Sandreas.hansson@arm.com
1118856Sandreas.hansson@arm.com        virtual void getDeviceAddressRanges(AddrRangeList &resp,
1123738Sstever@eecs.umich.edu                                            bool &snoop);
1133738Sstever@eecs.umich.edu
1148856Sandreas.hansson@arm.com        virtual bool recvTiming(PacketPtr pkt);
1158914Sandreas.hansson@arm.com
1168914Sandreas.hansson@arm.com        virtual void recvRetry();
1178914Sandreas.hansson@arm.com
1188914Sandreas.hansson@arm.com        virtual Tick recvAtomic(PacketPtr pkt);
1198914Sandreas.hansson@arm.com
1208975Sandreas.hansson@arm.com        virtual void recvFunctional(PacketPtr pkt);
1218914Sandreas.hansson@arm.com
1228914Sandreas.hansson@arm.com        typedef EventWrapper<MemSidePort, &MemSidePort::processSendEvent>
1238914Sandreas.hansson@arm.com                SendEvent;
1248914Sandreas.hansson@arm.com    };
1258914Sandreas.hansson@arm.com
1268914Sandreas.hansson@arm.com    /** Tag and data Storage */
1278914Sandreas.hansson@arm.com    TagStore *tags;
1288914Sandreas.hansson@arm.com
1298975Sandreas.hansson@arm.com    /** Prefetcher */
1308914Sandreas.hansson@arm.com    BasePrefetcher *prefetcher;
1318975Sandreas.hansson@arm.com
1328914Sandreas.hansson@arm.com    /** Temporary cache block for occasional transitory use */
1338914Sandreas.hansson@arm.com    BlkType *tempBlock;
1348914Sandreas.hansson@arm.com
1358914Sandreas.hansson@arm.com    /**
1368914Sandreas.hansson@arm.com     * Can this cache should allocate a block on a line-sized write miss.
1378914Sandreas.hansson@arm.com     */
1388914Sandreas.hansson@arm.com    const bool doFastWrites;
1398914Sandreas.hansson@arm.com
1408914Sandreas.hansson@arm.com    const bool prefetchMiss;
1418914Sandreas.hansson@arm.com
1428914Sandreas.hansson@arm.com    /**
1438856Sandreas.hansson@arm.com     * Handle a replacement for the given request.
1448856Sandreas.hansson@arm.com     * @param blk A pointer to the block, usually NULL
1458856Sandreas.hansson@arm.com     * @param pkt The memory request to satisfy.
1468856Sandreas.hansson@arm.com     * @param new_state The new state of the block.
1473738Sstever@eecs.umich.edu     * @param writebacks A list to store any generated writebacks.
1488856Sandreas.hansson@arm.com     */
1493738Sstever@eecs.umich.edu    BlkType* doReplacement(BlkType *blk, PacketPtr pkt,
1508914Sandreas.hansson@arm.com                           CacheBlk::State new_state, PacketList &writebacks);
1518914Sandreas.hansson@arm.com
1528914Sandreas.hansson@arm.com    /**
1538856Sandreas.hansson@arm.com     * Does all the processing necessary to perform the provided request.
1548856Sandreas.hansson@arm.com     * @param pkt The memory request to perform.
1553738Sstever@eecs.umich.edu     * @param lat The latency of the access.
1568856Sandreas.hansson@arm.com     * @param writebacks List for any writebacks that need to be performed.
1574478Sstever@eecs.umich.edu     * @param update True if the replacement data should be updated.
1588975Sandreas.hansson@arm.com     * @return Pointer to the cache block touched by the request. NULL if it
1598948Sandreas.hansson@arm.com     * was a miss.
1608975Sandreas.hansson@arm.com     */
1613738Sstever@eecs.umich.edu    bool access(PacketPtr pkt, BlkType *&blk, int &lat);
1628948Sandreas.hansson@arm.com
1633738Sstever@eecs.umich.edu    /**
1648948Sandreas.hansson@arm.com     *Handle doing the Compare and Swap function for SPARC.
1654458Sstever@eecs.umich.edu     */
1668856Sandreas.hansson@arm.com    void cmpAndSwap(BlkType *blk, PacketPtr pkt);
1678856Sandreas.hansson@arm.com
1688856Sandreas.hansson@arm.com    /**
1698856Sandreas.hansson@arm.com     * Populates a cache block and handles all outstanding requests for the
1708856Sandreas.hansson@arm.com     * satisfied fill request. This version takes two memory requests. One
1718856Sandreas.hansson@arm.com     * contains the fill data, the other is an optional target to satisfy.
1728856Sandreas.hansson@arm.com     * Used for Cache::probe.
1733738Sstever@eecs.umich.edu     * @param pkt The memory request with the fill data.
1743738Sstever@eecs.umich.edu     * @param blk The cache block if it already exists.
1752810Srdreslin@umich.edu     * @param writebacks List for any writebacks that need to be performed.
1762810Srdreslin@umich.edu     * @return Pointer to the new cache block.
1774626Sstever@eecs.umich.edu     */
1782810Srdreslin@umich.edu    BlkType *handleFill(PacketPtr pkt, BlkType *blk,
1793861Sstever@eecs.umich.edu                        PacketList &writebacks);
1802810Srdreslin@umich.edu
1814671Sstever@eecs.umich.edu    void satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk);
1824671Sstever@eecs.umich.edu    bool satisfyMSHR(MSHR *mshr, PacketPtr pkt, BlkType *blk);
1834671Sstever@eecs.umich.edu
1842810Srdreslin@umich.edu    void doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data,
1855707Shsul@eecs.umich.edu                                bool already_copied);
1863860Sstever@eecs.umich.edu
1873860Sstever@eecs.umich.edu    /**
1883860Sstever@eecs.umich.edu     * Sets the blk to the new state.
1895875Ssteve.reinhardt@amd.com     * @param blk The cache block being snooped.
1905875Ssteve.reinhardt@amd.com     * @param new_state The new coherence state for the block.
1915875Ssteve.reinhardt@amd.com     */
1925875Ssteve.reinhardt@amd.com    void handleSnoop(PacketPtr ptk, BlkType *blk,
1933860Sstever@eecs.umich.edu                     bool is_timing, bool is_deferred);
1943860Sstever@eecs.umich.edu
1959063SAli.Saidi@ARM.com    /**
1969063SAli.Saidi@ARM.com     * Create a writeback request for the given block.
1979063SAli.Saidi@ARM.com     * @param blk The block to writeback.
1989063SAli.Saidi@ARM.com     * @return The writeback request for the block.
1999063SAli.Saidi@ARM.com     */
2009063SAli.Saidi@ARM.com    PacketPtr writebackBlk(BlkType *blk);
2019063SAli.Saidi@ARM.com
2023860Sstever@eecs.umich.edu  public:
2033860Sstever@eecs.umich.edu
2043860Sstever@eecs.umich.edu    class Params
2053860Sstever@eecs.umich.edu    {
2063860Sstever@eecs.umich.edu      public:
2075707Shsul@eecs.umich.edu        TagStore *tags;
2083860Sstever@eecs.umich.edu        BaseCache::Params baseParams;
2095388Sstever@gmail.com        BasePrefetcher*prefetcher;
2109288Sandreas.hansson@arm.com        bool prefetchAccess;
2114219Srdreslin@umich.edu        const bool doFastWrites;
2124219Srdreslin@umich.edu        const bool prefetchMiss;
2134219Srdreslin@umich.edu
2144219Srdreslin@umich.edu        Params(TagStore *_tags,
2154626Sstever@eecs.umich.edu               BaseCache::Params params,
2163860Sstever@eecs.umich.edu               BasePrefetcher *_prefetcher,
2173860Sstever@eecs.umich.edu               bool prefetch_access, int hit_latency,
2185350Sstever@gmail.com               bool do_fast_writes,
2195350Sstever@gmail.com               bool prefetch_miss)
2205350Sstever@gmail.com            : tags(_tags),
2215350Sstever@gmail.com              baseParams(params),
2225350Sstever@gmail.com              prefetcher(_prefetcher), prefetchAccess(prefetch_access),
2235350Sstever@gmail.com              doFastWrites(do_fast_writes),
2245350Sstever@gmail.com              prefetchMiss(prefetch_miss)
2255350Sstever@gmail.com        {
2263860Sstever@eecs.umich.edu        }
2273860Sstever@eecs.umich.edu    };
2283860Sstever@eecs.umich.edu
2294626Sstever@eecs.umich.edu    /** Instantiates a basic cache object. */
2303860Sstever@eecs.umich.edu    Cache(const std::string &_name, Params &params);
2313860Sstever@eecs.umich.edu
2323860Sstever@eecs.umich.edu    virtual Port *getPort(const std::string &if_name, int idx = -1);
2333860Sstever@eecs.umich.edu    virtual void deletePortRefs(Port *p);
2344626Sstever@eecs.umich.edu
2354626Sstever@eecs.umich.edu    void regStats();
2363860Sstever@eecs.umich.edu
2379548Sandreas.hansson@arm.com    /**
2389548Sandreas.hansson@arm.com     * Performs the access specified by the request.
2399548Sandreas.hansson@arm.com     * @param pkt The request to perform.
2409548Sandreas.hansson@arm.com     * @return The result of the access.
2419548Sandreas.hansson@arm.com     */
2429548Sandreas.hansson@arm.com    bool timingAccess(PacketPtr pkt);
2439548Sandreas.hansson@arm.com
2449548Sandreas.hansson@arm.com    /**
2459548Sandreas.hansson@arm.com     * Performs the access specified by the request.
2469548Sandreas.hansson@arm.com     * @param pkt The request to perform.
2479548Sandreas.hansson@arm.com     * @return The result of the access.
2489548Sandreas.hansson@arm.com     */
2499548Sandreas.hansson@arm.com    Tick atomicAccess(PacketPtr pkt);
2509548Sandreas.hansson@arm.com
2519548Sandreas.hansson@arm.com    /**
2529548Sandreas.hansson@arm.com     * Performs the access specified by the request.
2539548Sandreas.hansson@arm.com     * @param pkt The request to perform.
2549548Sandreas.hansson@arm.com     * @return The result of the access.
2559548Sandreas.hansson@arm.com     */
2569548Sandreas.hansson@arm.com    void functionalAccess(PacketPtr pkt, CachePort *otherSidePort);
2579548Sandreas.hansson@arm.com
2589548Sandreas.hansson@arm.com    /**
2599548Sandreas.hansson@arm.com     * Handles a response (cache line fill/write ack) from the bus.
2609548Sandreas.hansson@arm.com     * @param pkt The request being responded to.
2619548Sandreas.hansson@arm.com     */
2629548Sandreas.hansson@arm.com    void handleResponse(PacketPtr pkt);
2639548Sandreas.hansson@arm.com
2649548Sandreas.hansson@arm.com    /**
2659548Sandreas.hansson@arm.com     * Snoops bus transactions to maintain coherence.
2669782Sandreas.hansson@arm.com     * @param pkt The current bus transaction.
2679548Sandreas.hansson@arm.com     */
2689782Sandreas.hansson@arm.com    void snoopTiming(PacketPtr pkt);
2699548Sandreas.hansson@arm.com
2709548Sandreas.hansson@arm.com    /**
2719548Sandreas.hansson@arm.com     * Snoop for the provided request in the cache and return the estimated
2729782Sandreas.hansson@arm.com     * time of completion.
2739548Sandreas.hansson@arm.com     * @param pkt The memory request to snoop
2749782Sandreas.hansson@arm.com     * @return The estimated completion time.
2759548Sandreas.hansson@arm.com     */
2769782Sandreas.hansson@arm.com    Tick snoopAtomic(PacketPtr pkt);
2779548Sandreas.hansson@arm.com
2789548Sandreas.hansson@arm.com    /**
2799548Sandreas.hansson@arm.com     * Squash all requests associated with specified thread.
2809548Sandreas.hansson@arm.com     * intended for use by I-cache.
2819548Sandreas.hansson@arm.com     * @param threadNum The thread to squash.
2829548Sandreas.hansson@arm.com     */
2839548Sandreas.hansson@arm.com    void squash(int threadNum);
2849548Sandreas.hansson@arm.com
2857667Ssteve.reinhardt@amd.com    /**
2867667Ssteve.reinhardt@amd.com     * Selects a outstanding request to service.
2877667Ssteve.reinhardt@amd.com     * @return The request to service, NULL if none found.
2884628Sstever@eecs.umich.edu     */
2894626Sstever@eecs.umich.edu    PacketPtr getBusPacket(PacketPtr cpu_pkt, BlkType *blk,
2904670Sstever@eecs.umich.edu                           bool needsExclusive);
2915319Sstever@gmail.com    MSHR *getNextMSHR();
2923860Sstever@eecs.umich.edu    PacketPtr getTimingPacket();
2933860Sstever@eecs.umich.edu
2943860Sstever@eecs.umich.edu    /**
2953860Sstever@eecs.umich.edu     * Marks a request as in service (sent on the bus). This can have side
2963860Sstever@eecs.umich.edu     * effect since storage for no response commands is deallocated once they
2973860Sstever@eecs.umich.edu     * are successfully sent.
2984670Sstever@eecs.umich.edu     * @param pkt The request that was sent on the bus.
2995319Sstever@gmail.com     */
3003860Sstever@eecs.umich.edu    void markInService(MSHR *mshr);
3013860Sstever@eecs.umich.edu
3023860Sstever@eecs.umich.edu    /**
3033860Sstever@eecs.umich.edu     * Perform the given writeback request.
3043860Sstever@eecs.umich.edu     * @param pkt The writeback request.
3053860Sstever@eecs.umich.edu     */
3063860Sstever@eecs.umich.edu    void doWriteback(PacketPtr pkt);
3073860Sstever@eecs.umich.edu
3089347SAndreas.Sandberg@arm.com    /**
3099347SAndreas.Sandberg@arm.com     * Return whether there are any outstanding misses.
3109347SAndreas.Sandberg@arm.com     */
3119347SAndreas.Sandberg@arm.com    bool outstandingMisses() const
3129347SAndreas.Sandberg@arm.com    {
3139347SAndreas.Sandberg@arm.com        return mshrQueue.allocated != 0;
3149347SAndreas.Sandberg@arm.com    }
3159347SAndreas.Sandberg@arm.com
3169347SAndreas.Sandberg@arm.com    CacheBlk *findBlock(Addr addr) {
3179347SAndreas.Sandberg@arm.com        return tags->findBlock(addr);
3189347SAndreas.Sandberg@arm.com    }
3199347SAndreas.Sandberg@arm.com
3209347SAndreas.Sandberg@arm.com    bool inCache(Addr addr) {
3219347SAndreas.Sandberg@arm.com        return (tags->findBlock(addr) != 0);
3229347SAndreas.Sandberg@arm.com    }
3239347SAndreas.Sandberg@arm.com
3249347SAndreas.Sandberg@arm.com    bool inMissQueue(Addr addr) {
3259347SAndreas.Sandberg@arm.com        return (mshrQueue.findMatch(addr) != 0);
3269347SAndreas.Sandberg@arm.com    }
3279347SAndreas.Sandberg@arm.com};
3289347SAndreas.Sandberg@arm.com
3299445SAndreas.Sandberg@ARM.com#endif // __CACHE_HH__
3309445SAndreas.Sandberg@ARM.com