mshr.hh revision 9663:45df88079f04
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Erik Hallnor
41 */
42
43/**
44 * @file
45 * Miss Status and Handling Register (MSHR) declaration.
46 */
47
48#ifndef __MSHR_HH__
49#define __MSHR_HH__
50
51#include <list>
52
53#include "base/printable.hh"
54#include "mem/packet.hh"
55
56class CacheBlk;
57class MSHRQueue;
58
59/**
60 * Miss Status and handling Register. This class keeps all the information
61 * needed to handle a cache miss including a list of target requests.
62 * @sa  \ref gem5MemorySystem "gem5 Memory System"
63 */
64class MSHR : public Packet::SenderState, public Printable
65{
66
67  public:
68
69    class Target {
70      public:
71
72        enum Source {
73            FromCPU,
74            FromSnoop,
75            FromPrefetcher
76        };
77
78        Tick recvTime;  //!< Time when request was received (for stats)
79        Tick readyTime; //!< Time when request is ready to be serviced
80        Counter order;  //!< Global order (for memory consistency mgmt)
81        PacketPtr pkt;  //!< Pending request packet.
82        Source source;  //!< Did request come from cpu, memory, or prefetcher?
83        bool markedPending; //!< Did we mark upstream MSHR
84                            //!<  as downstreamPending?
85
86        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
87               Source _source, bool _markedPending)
88            : recvTime(curTick()), readyTime(_readyTime), order(_order),
89              pkt(_pkt), source(_source), markedPending(_markedPending)
90        {}
91    };
92
93    class TargetList : public std::list<Target> {
94        /** Target list iterator. */
95        typedef std::list<Target>::iterator Iterator;
96        typedef std::list<Target>::const_iterator ConstIterator;
97
98      public:
99        bool needsExclusive;
100        bool hasUpgrade;
101
102        TargetList();
103        void resetFlags() { needsExclusive = hasUpgrade = false; }
104        bool isReset()    { return !needsExclusive && !hasUpgrade; }
105        void add(PacketPtr pkt, Tick readyTime, Counter order,
106                 Target::Source source, bool markPending);
107        void replaceUpgrades();
108        void clearDownstreamPending();
109        bool checkFunctional(PacketPtr pkt);
110        void print(std::ostream &os, int verbosity,
111                   const std::string &prefix) const;
112    };
113
114    /** A list of MSHRs. */
115    typedef std::list<MSHR *> List;
116    /** MSHR list iterator. */
117    typedef List::iterator Iterator;
118    /** MSHR list const_iterator. */
119    typedef List::const_iterator ConstIterator;
120
121    /** Pointer to queue containing this MSHR. */
122    MSHRQueue *queue;
123
124    /** Cycle when ready to issue */
125    Tick readyTime;
126
127    /** Order number assigned by the miss queue. */
128    Counter order;
129
130    /** Address of the request. */
131    Addr addr;
132
133    /** Size of the request. */
134    int size;
135
136    /** True if the request has been sent to the bus. */
137    bool inService;
138
139    /** True if the request is just a simple forward from an upper level */
140    bool isForward;
141
142    /** True if we need to get an exclusive copy of the block. */
143    bool needsExclusive() const { return targets->needsExclusive; }
144
145    /** True if the request is uncacheable */
146    bool _isUncacheable;
147
148    bool downstreamPending;
149
150    /** The pending* and post* flags are only valid if inService is
151     *  true.  Using the accessor functions lets us detect if these
152     *  flags are accessed improperly.
153     */
154
155    /** Will we have a dirty copy after this request? */
156    bool pendingDirty;
157    bool isPendingDirty() const {
158        assert(inService); return pendingDirty;
159    }
160
161    /** Did we snoop an invalidate while waiting for data? */
162    bool postInvalidate;
163    bool hasPostInvalidate() const {
164        assert(inService); return postInvalidate;
165    }
166
167    /** Did we snoop a read while waiting for data? */
168    bool postDowngrade;
169    bool hasPostDowngrade() const {
170        assert(inService); return postDowngrade;
171    }
172
173    /** Thread number of the miss. */
174    ThreadID threadNum;
175    /** The number of currently allocated targets. */
176    unsigned short ntargets;
177
178
179    /** Data buffer (if needed).  Currently used only for pending
180     * upgrade handling. */
181    uint8_t *data;
182
183    /**
184     * Pointer to this MSHR on the ready list.
185     * @sa MissQueue, MSHRQueue::readyList
186     */
187    Iterator readyIter;
188
189    /**
190     * Pointer to this MSHR on the allocated list.
191     * @sa MissQueue, MSHRQueue::allocatedList
192     */
193    Iterator allocIter;
194
195private:
196    /** List of all requests that match the address */
197    TargetList *targets;
198
199    TargetList *deferredTargets;
200
201public:
202
203    bool isUncacheable() { return _isUncacheable; }
204
205    /**
206     * Allocate a miss to this MSHR.
207     * @param cmd The requesting command.
208     * @param addr The address of the miss.
209     * @param asid The address space id of the miss.
210     * @param size The number of bytes to request.
211     * @param pkt  The original miss.
212     */
213    void allocate(Addr addr, int size, PacketPtr pkt,
214                  Tick when, Counter _order);
215
216    bool markInService(PacketPtr pkt);
217
218    void clearDownstreamPending();
219
220    /**
221     * Mark this MSHR as free.
222     */
223    void deallocate();
224
225    /**
226     * Add a request to the list of targets.
227     * @param target The target.
228     */
229    void allocateTarget(PacketPtr target, Tick when, Counter order);
230    bool handleSnoop(PacketPtr target, Counter order);
231
232    /** A simple constructor. */
233    MSHR();
234    /** A simple destructor. */
235    ~MSHR();
236
237    /**
238     * Returns the current number of allocated targets.
239     * @return The current number of allocated targets.
240     */
241    int getNumTargets() const { return ntargets; }
242
243    /**
244     * Returns a pointer to the target list.
245     * @return a pointer to the target list.
246     */
247    TargetList *getTargetList() { return targets; }
248
249    /**
250     * Returns true if there are targets left.
251     * @return true if there are targets
252     */
253    bool hasTargets() const { return !targets->empty(); }
254
255    /**
256     * Returns a reference to the first target.
257     * @return A pointer to the first target.
258     */
259    Target *getTarget() const
260    {
261        assert(hasTargets());
262        return &targets->front();
263    }
264
265    /**
266     * Pop first target.
267     */
268    void popTarget()
269    {
270        --ntargets;
271        targets->pop_front();
272    }
273
274    bool isForwardNoResponse() const
275    {
276        if (getNumTargets() != 1)
277            return false;
278        Target *tgt = getTarget();
279        return tgt->source == Target::FromCPU && !tgt->pkt->needsResponse();
280    }
281
282    bool promoteDeferredTargets();
283
284    void handleFill(Packet *pkt, CacheBlk *blk);
285
286    bool checkFunctional(PacketPtr pkt);
287
288    /**
289     * Prints the contents of this MSHR for debugging.
290     */
291    void print(std::ostream &os,
292               int verbosity = 0,
293               const std::string &prefix = "") const;
294    /**
295     * A no-args wrapper of print(std::ostream...)  meant to be
296     * invoked from DPRINTFs avoiding string overheads in fast mode
297     *
298     * @return string with mshr fields + [deferred]targets
299     */
300    std::string print() const;
301};
302
303#endif //__MSHR_HH__
304