cache.hh revision 8229:78bf55f23338
1/*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Erik Hallnor
29 *          Dave Greene
30 *          Steve Reinhardt
31 *          Ron Dreslinski
32 */
33
34/**
35 * @file
36 * Describes a cache based on template policies.
37 */
38
39#ifndef __CACHE_HH__
40#define __CACHE_HH__
41
42#include "base/misc.hh" // fatal, panic, and warn
43#include "mem/cache/base.hh"
44#include "mem/cache/blk.hh"
45#include "mem/cache/mshr.hh"
46#include "sim/eventq.hh"
47
48//Forward decleration
49class BasePrefetcher;
50
51/**
52 * A template-policy based cache. The behavior of the cache can be altered by
53 * supplying different template policies. TagStore handles all tag and data
54 * storage @sa TagStore.
55 */
56template <class TagStore>
57class Cache : public BaseCache
58{
59  public:
60    /** Define the type of cache block to use. */
61    typedef typename TagStore::BlkType BlkType;
62    /** A typedef for a list of BlkType pointers. */
63    typedef typename TagStore::BlkList BlkList;
64
65  protected:
66
67    class CpuSidePort : public CachePort
68    {
69      public:
70        CpuSidePort(const std::string &_name,
71                    Cache<TagStore> *_cache,
72                    const std::string &_label);
73
74        // BaseCache::CachePort just has a BaseCache *; this function
75        // lets us get back the type info we lost when we stored the
76        // cache pointer there.
77        Cache<TagStore> *myCache() {
78            return static_cast<Cache<TagStore> *>(cache);
79        }
80
81        virtual void getDeviceAddressRanges(AddrRangeList &resp,
82                                            bool &snoop);
83
84        virtual bool recvTiming(PacketPtr pkt);
85
86        virtual Tick recvAtomic(PacketPtr pkt);
87
88        virtual void recvFunctional(PacketPtr pkt);
89    };
90
91    class MemSidePort : public CachePort
92    {
93      public:
94        MemSidePort(const std::string &_name,
95                    Cache<TagStore> *_cache,
96                    const std::string &_label);
97
98        // BaseCache::CachePort just has a BaseCache *; this function
99        // lets us get back the type info we lost when we stored the
100        // cache pointer there.
101        Cache<TagStore> *myCache() {
102            return static_cast<Cache<TagStore> *>(cache);
103        }
104
105        void sendPacket();
106
107        void processSendEvent();
108
109        virtual void getDeviceAddressRanges(AddrRangeList &resp,
110                                            bool &snoop);
111
112        virtual bool recvTiming(PacketPtr pkt);
113
114        virtual void recvRetry();
115
116        virtual Tick recvAtomic(PacketPtr pkt);
117
118        virtual void recvFunctional(PacketPtr pkt);
119
120        typedef EventWrapper<MemSidePort, &MemSidePort::processSendEvent>
121                SendEvent;
122    };
123
124    /** Tag and data Storage */
125    TagStore *tags;
126
127    /** Prefetcher */
128    BasePrefetcher *prefetcher;
129
130    /** Temporary cache block for occasional transitory use */
131    BlkType *tempBlock;
132
133    /**
134     * This cache should allocate a block on a line-sized write miss.
135     */
136    const bool doFastWrites;
137
138    /**
139     * Notify the prefetcher on every access, not just misses.
140     */
141    const bool prefetchOnAccess;
142
143    /**
144     * Does all the processing necessary to perform the provided request.
145     * @param pkt The memory request to perform.
146     * @param lat The latency of the access.
147     * @param writebacks List for any writebacks that need to be performed.
148     * @param update True if the replacement data should be updated.
149     * @return Boolean indicating whether the request was satisfied.
150     */
151    bool access(PacketPtr pkt, BlkType *&blk,
152                int &lat, PacketList &writebacks);
153
154    /**
155     *Handle doing the Compare and Swap function for SPARC.
156     */
157    void cmpAndSwap(BlkType *blk, PacketPtr pkt);
158
159    /**
160     * Find a block frame for new block at address addr, assuming that
161     * the block is not currently in the cache.  Append writebacks if
162     * any to provided packet list.  Return free block frame.  May
163     * return NULL if there are no replaceable blocks at the moment.
164     */
165    BlkType *allocateBlock(Addr addr, PacketList &writebacks);
166
167    /**
168     * Populates a cache block and handles all outstanding requests for the
169     * satisfied fill request. This version takes two memory requests. One
170     * contains the fill data, the other is an optional target to satisfy.
171     * @param pkt The memory request with the fill data.
172     * @param blk The cache block if it already exists.
173     * @param writebacks List for any writebacks that need to be performed.
174     * @return Pointer to the new cache block.
175     */
176    BlkType *handleFill(PacketPtr pkt, BlkType *blk,
177                        PacketList &writebacks);
178
179    void satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk,
180                               bool deferred_response = false,
181                               bool pending_downgrade = false);
182    bool satisfyMSHR(MSHR *mshr, PacketPtr pkt, BlkType *blk);
183
184    void doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data,
185                                bool already_copied, bool pending_inval);
186
187    /**
188     * Sets the blk to the new state.
189     * @param blk The cache block being snooped.
190     * @param new_state The new coherence state for the block.
191     */
192    void handleSnoop(PacketPtr ptk, BlkType *blk,
193                     bool is_timing, bool is_deferred, bool pending_inval);
194
195    /**
196     * Create a writeback request for the given block.
197     * @param blk The block to writeback.
198     * @return The writeback request for the block.
199     */
200    PacketPtr writebackBlk(BlkType *blk);
201
202  public:
203    /** Instantiates a basic cache object. */
204    Cache(const Params *p, TagStore *tags, BasePrefetcher *prefetcher);
205
206    virtual Port *getPort(const std::string &if_name, int idx = -1);
207    virtual void deletePortRefs(Port *p);
208
209    void regStats();
210
211    /**
212     * Performs the access specified by the request.
213     * @param pkt The request to perform.
214     * @return The result of the access.
215     */
216    bool timingAccess(PacketPtr pkt);
217
218    /**
219     * Performs the access specified by the request.
220     * @param pkt The request to perform.
221     * @return The result of the access.
222     */
223    Tick atomicAccess(PacketPtr pkt);
224
225    /**
226     * Performs the access specified by the request.
227     * @param pkt The request to perform.
228     * @return The result of the access.
229     */
230    void functionalAccess(PacketPtr pkt, CachePort *incomingPort,
231                          CachePort *otherSidePort);
232
233    /**
234     * Handles a response (cache line fill/write ack) from the bus.
235     * @param pkt The request being responded to.
236     */
237    void handleResponse(PacketPtr pkt);
238
239    /**
240     * Snoops bus transactions to maintain coherence.
241     * @param pkt The current bus transaction.
242     */
243    void snoopTiming(PacketPtr pkt);
244
245    /**
246     * Snoop for the provided request in the cache and return the estimated
247     * time of completion.
248     * @param pkt The memory request to snoop
249     * @return The estimated completion time.
250     */
251    Tick snoopAtomic(PacketPtr pkt);
252
253    /**
254     * Squash all requests associated with specified thread.
255     * intended for use by I-cache.
256     * @param threadNum The thread to squash.
257     */
258    void squash(int threadNum);
259
260    /**
261     * Generate an appropriate downstream bus request packet for the
262     * given parameters.
263     * @param cpu_pkt  The upstream request that needs to be satisfied.
264     * @param blk The block currently in the cache corresponding to
265     * cpu_pkt (NULL if none).
266     * @param needsExclusive  Indicates that an exclusive copy is required
267     * even if the request in cpu_pkt doesn't indicate that.
268     * @return A new Packet containing the request, or NULL if the
269     * current request in cpu_pkt should just be forwarded on.
270     */
271    PacketPtr getBusPacket(PacketPtr cpu_pkt, BlkType *blk,
272                           bool needsExclusive);
273
274    /**
275     * Return the next MSHR to service, either a pending miss from the
276     * mshrQueue, a buffered write from the write buffer, or something
277     * from the prefetcher.  This function is responsible for
278     * prioritizing among those sources on the fly.
279     */
280    MSHR *getNextMSHR();
281
282    /**
283     * Selects an outstanding request to service.  Called when the
284     * cache gets granted the downstream bus in timing mode.
285     * @return The request to service, NULL if none found.
286     */
287    PacketPtr getTimingPacket();
288
289    /**
290     * Marks a request as in service (sent on the bus). This can have side
291     * effect since storage for no response commands is deallocated once they
292     * are successfully sent.
293     * @param pkt The request that was sent on the bus.
294     */
295    void markInService(MSHR *mshr, PacketPtr pkt = 0);
296
297    /**
298     * Perform the given writeback request.
299     * @param pkt The writeback request.
300     */
301    void doWriteback(PacketPtr pkt);
302
303    /**
304     * Return whether there are any outstanding misses.
305     */
306    bool outstandingMisses() const
307    {
308        return mshrQueue.allocated != 0;
309    }
310
311    CacheBlk *findBlock(Addr addr) {
312        return tags->findBlock(addr);
313    }
314
315    bool inCache(Addr addr) {
316        return (tags->findBlock(addr) != 0);
317    }
318
319    bool inMissQueue(Addr addr) {
320        return (mshrQueue.findMatch(addr) != 0);
321    }
322
323    /**
324     * Find next request ready time from among possible sources.
325     */
326    Tick nextMSHRReadyTime();
327};
328
329#endif // __CACHE_HH__
330