cache.hh revision 5875:d82be3235ab4
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
44#include "mem/cache/base.hh"
45#include "mem/cache/blk.hh"
46#include "mem/cache/mshr.hh"
47
48#include "sim/eventq.hh"
49
50//Forward decleration
51class BasePrefetcher;
52
53/**
54 * A template-policy based cache. The behavior of the cache can be altered by
55 * supplying different template policies. TagStore handles all tag and data
56 * storage @sa TagStore.
57 */
58template <class TagStore>
59class Cache : public BaseCache
60{
61  public:
62    /** Define the type of cache block to use. */
63    typedef typename TagStore::BlkType BlkType;
64    /** A typedef for a list of BlkType pointers. */
65    typedef typename TagStore::BlkList BlkList;
66
67  protected:
68
69    class CpuSidePort : public CachePort
70    {
71      public:
72        CpuSidePort(const std::string &_name,
73                    Cache<TagStore> *_cache,
74                    const std::string &_label,
75                    std::vector<Range<Addr> > filterRanges);
76
77        // BaseCache::CachePort just has a BaseCache *; this function
78        // lets us get back the type info we lost when we stored the
79        // cache pointer there.
80        Cache<TagStore> *myCache() {
81            return static_cast<Cache<TagStore> *>(cache);
82        }
83
84        virtual void getDeviceAddressRanges(AddrRangeList &resp,
85                                            bool &snoop);
86
87        virtual bool recvTiming(PacketPtr pkt);
88
89        virtual Tick recvAtomic(PacketPtr pkt);
90
91        virtual void recvFunctional(PacketPtr pkt);
92    };
93
94    class MemSidePort : public CachePort
95    {
96      public:
97        MemSidePort(const std::string &_name,
98                    Cache<TagStore> *_cache,
99                    const std::string &_label,
100                    std::vector<Range<Addr> > filterRanges);
101
102        // BaseCache::CachePort just has a BaseCache *; this function
103        // lets us get back the type info we lost when we stored the
104        // cache pointer there.
105        Cache<TagStore> *myCache() {
106            return static_cast<Cache<TagStore> *>(cache);
107        }
108
109        void sendPacket();
110
111        void processSendEvent();
112
113        virtual void getDeviceAddressRanges(AddrRangeList &resp,
114                                            bool &snoop);
115
116        virtual bool recvTiming(PacketPtr pkt);
117
118        virtual void recvRetry();
119
120        virtual Tick recvAtomic(PacketPtr pkt);
121
122        virtual void recvFunctional(PacketPtr pkt);
123
124        typedef EventWrapper<MemSidePort, &MemSidePort::processSendEvent>
125                SendEvent;
126    };
127
128    /** Tag and data Storage */
129    TagStore *tags;
130
131    /** Prefetcher */
132    BasePrefetcher *prefetcher;
133
134    /** Temporary cache block for occasional transitory use */
135    BlkType *tempBlock;
136
137    /**
138     * This cache should allocate a block on a line-sized write miss.
139     */
140    const bool doFastWrites;
141
142    /**
143     * Notify the prefetcher on every access, not just misses.
144     */
145    const bool prefetchOnAccess;
146
147    /**
148     * Does all the processing necessary to perform the provided request.
149     * @param pkt The memory request to perform.
150     * @param lat The latency of the access.
151     * @param writebacks List for any writebacks that need to be performed.
152     * @param update True if the replacement data should be updated.
153     * @return Boolean indicating whether the request was satisfied.
154     */
155    bool access(PacketPtr pkt, BlkType *&blk,
156                int &lat, PacketList &writebacks);
157
158    /**
159     *Handle doing the Compare and Swap function for SPARC.
160     */
161    void cmpAndSwap(BlkType *blk, PacketPtr pkt);
162
163    /**
164     * Find a block frame for new block at address addr, assuming that
165     * the block is not currently in the cache.  Append writebacks if
166     * any to provided packet list.  Return free block frame.  May
167     * return NULL if there are no replaceable blocks at the moment.
168     */
169    BlkType *allocateBlock(Addr addr, PacketList &writebacks);
170
171    /**
172     * Populates a cache block and handles all outstanding requests for the
173     * satisfied fill request. This version takes two memory requests. One
174     * contains the fill data, the other is an optional target to satisfy.
175     * @param pkt The memory request with the fill data.
176     * @param blk The cache block if it already exists.
177     * @param writebacks List for any writebacks that need to be performed.
178     * @return Pointer to the new cache block.
179     */
180    BlkType *handleFill(PacketPtr pkt, BlkType *blk,
181                        PacketList &writebacks);
182
183    void satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk);
184    bool satisfyMSHR(MSHR *mshr, PacketPtr pkt, BlkType *blk);
185
186    void doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data,
187                                bool already_copied, bool pending_inval);
188
189    /**
190     * Sets the blk to the new state.
191     * @param blk The cache block being snooped.
192     * @param new_state The new coherence state for the block.
193     */
194    void handleSnoop(PacketPtr ptk, BlkType *blk,
195                     bool is_timing, bool is_deferred, bool pending_inval);
196
197    /**
198     * Create a writeback request for the given block.
199     * @param blk The block to writeback.
200     * @return The writeback request for the block.
201     */
202    PacketPtr writebackBlk(BlkType *blk);
203
204  public:
205    /** Instantiates a basic cache object. */
206    Cache(const Params *p, TagStore *tags, BasePrefetcher *prefetcher);
207
208    virtual Port *getPort(const std::string &if_name, int idx = -1);
209    virtual void deletePortRefs(Port *p);
210
211    void regStats();
212
213    /**
214     * Performs the access specified by the request.
215     * @param pkt The request to perform.
216     * @return The result of the access.
217     */
218    bool timingAccess(PacketPtr pkt);
219
220    /**
221     * Performs the access specified by the request.
222     * @param pkt The request to perform.
223     * @return The result of the access.
224     */
225    Tick atomicAccess(PacketPtr pkt);
226
227    /**
228     * Performs the access specified by the request.
229     * @param pkt The request to perform.
230     * @return The result of the access.
231     */
232    void functionalAccess(PacketPtr pkt, CachePort *incomingPort,
233                          CachePort *otherSidePort);
234
235    /**
236     * Handles a response (cache line fill/write ack) from the bus.
237     * @param pkt The request being responded to.
238     */
239    void handleResponse(PacketPtr pkt);
240
241    /**
242     * Snoops bus transactions to maintain coherence.
243     * @param pkt The current bus transaction.
244     */
245    void snoopTiming(PacketPtr pkt);
246
247    /**
248     * Snoop for the provided request in the cache and return the estimated
249     * time of completion.
250     * @param pkt The memory request to snoop
251     * @return The estimated completion time.
252     */
253    Tick snoopAtomic(PacketPtr pkt);
254
255    /**
256     * Squash all requests associated with specified thread.
257     * intended for use by I-cache.
258     * @param threadNum The thread to squash.
259     */
260    void squash(int threadNum);
261
262    /**
263     * Generate an appropriate downstream bus request packet for the
264     * given parameters.
265     * @param cpu_pkt  The upstream request that needs to be satisfied.
266     * @param blk The block currently in the cache corresponding to
267     * cpu_pkt (NULL if none).
268     * @param needsExclusive  Indicates that an exclusive copy is required
269     * even if the request in cpu_pkt doesn't indicate that.
270     * @return A new Packet containing the request, or NULL if the
271     * current request in cpu_pkt should just be forwarded on.
272     */
273    PacketPtr getBusPacket(PacketPtr cpu_pkt, BlkType *blk,
274                           bool needsExclusive);
275
276    /**
277     * Return the next MSHR to service, either a pending miss from the
278     * mshrQueue, a buffered write from the write buffer, or something
279     * from the prefetcher.  This function is responsible for
280     * prioritizing among those sources on the fly.
281     */
282    MSHR *getNextMSHR();
283
284    /**
285     * Selects an outstanding request to service.  Called when the
286     * cache gets granted the downstream bus in timing mode.
287     * @return The request to service, NULL if none found.
288     */
289    PacketPtr getTimingPacket();
290
291    /**
292     * Marks a request as in service (sent on the bus). This can have side
293     * effect since storage for no response commands is deallocated once they
294     * are successfully sent.
295     * @param pkt The request that was sent on the bus.
296     */
297    void markInService(MSHR *mshr);
298
299    /**
300     * Perform the given writeback request.
301     * @param pkt The writeback request.
302     */
303    void doWriteback(PacketPtr pkt);
304
305    /**
306     * Return whether there are any outstanding misses.
307     */
308    bool outstandingMisses() const
309    {
310        return mshrQueue.allocated != 0;
311    }
312
313    CacheBlk *findBlock(Addr addr) {
314        return tags->findBlock(addr);
315    }
316
317    bool inCache(Addr addr) {
318        return (tags->findBlock(addr) != 0);
319    }
320
321    bool inMissQueue(Addr addr) {
322        return (mshrQueue.findMatch(addr) != 0);
323    }
324
325    /**
326     * Find next request ready time from among possible sources.
327     */
328    Tick nextMSHRReadyTime();
329};
330
331#endif // __CACHE_HH__
332