mshr.hh revision 5318
15390SN/A/*
25443SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
35390SN/A * All rights reserved.
45390SN/A *
55390SN/A * Redistribution and use in source and binary forms, with or without
65390SN/A * modification, are permitted provided that the following conditions are
75390SN/A * met: redistributions of source code must retain the above copyright
85390SN/A * notice, this list of conditions and the following disclaimer;
95390SN/A * redistributions in binary form must reproduce the above copyright
105390SN/A * notice, this list of conditions and the following disclaimer in the
115390SN/A * documentation and/or other materials provided with the distribution;
125390SN/A * neither the name of the copyright holders nor the names of its
135390SN/A * contributors may be used to endorse or promote products derived from
145390SN/A * this software without specific prior written permission.
155390SN/A *
165390SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175390SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185390SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195390SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205390SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215390SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225390SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235390SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245390SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255390SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265390SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275390SN/A *
285390SN/A * Authors: Erik Hallnor
295390SN/A */
305390SN/A
315636Sgblack@eecs.umich.edu/**
325636Sgblack@eecs.umich.edu * @file
335390SN/A * Miss Status and Handling Register (MSHR) declaration.
345443SN/A */
355636Sgblack@eecs.umich.edu
365636Sgblack@eecs.umich.edu#ifndef __MSHR_HH__
375443SN/A#define __MSHR_HH__
385390SN/A
395390SN/A#include <list>
405390SN/A
415827Sgblack@eecs.umich.edu#include "base/printable.hh"
425636Sgblack@eecs.umich.edu#include "mem/packet.hh"
435636Sgblack@eecs.umich.edu
445390SN/Aclass CacheBlk;
455636Sgblack@eecs.umich.educlass MSHRQueue;
465636Sgblack@eecs.umich.edu
475642Sgblack@eecs.umich.edu/**
485642Sgblack@eecs.umich.edu * Miss Status and handling Register. This class keeps all the information
495642Sgblack@eecs.umich.edu * needed to handle a cache miss including a list of target requests.
505642Sgblack@eecs.umich.edu */
515642Sgblack@eecs.umich.educlass MSHR : public Packet::SenderState, public Printable
525642Sgblack@eecs.umich.edu{
535642Sgblack@eecs.umich.edu
545642Sgblack@eecs.umich.edu  public:
555642Sgblack@eecs.umich.edu
565642Sgblack@eecs.umich.edu    class Target {
575642Sgblack@eecs.umich.edu      public:
585642Sgblack@eecs.umich.edu        Tick recvTime;  //!< Time when request was received (for stats)
595642Sgblack@eecs.umich.edu        Tick readyTime; //!< Time when request is ready to be serviced
605642Sgblack@eecs.umich.edu        Counter order;  //!< Global order (for memory consistency mgmt)
615642Sgblack@eecs.umich.edu        PacketPtr pkt;  //!< Pending request packet.
625642Sgblack@eecs.umich.edu        bool cpuSide;   //!< Did request come from cpu side or mem side?
635642Sgblack@eecs.umich.edu        bool markedPending; //!< Did we mark upstream MSHR
6411320Ssteve.reinhardt@amd.com                            //!<  as downstreamPending?
655642Sgblack@eecs.umich.edu
665390SN/A        bool isCpuSide() const { return cpuSide; }
675827Sgblack@eecs.umich.edu
6811320Ssteve.reinhardt@amd.com        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
695642Sgblack@eecs.umich.edu               bool _cpuSide, bool _markedPending)
705390SN/A            : recvTime(curTick), readyTime(_readyTime), order(_order),
715636Sgblack@eecs.umich.edu              pkt(_pkt), cpuSide(_cpuSide), markedPending(_markedPending)
725636Sgblack@eecs.umich.edu        {}
735636Sgblack@eecs.umich.edu    };
745636Sgblack@eecs.umich.edu
755636Sgblack@eecs.umich.edu    class TargetList : public std::list<Target> {
765636Sgblack@eecs.umich.edu        /** Target list iterator. */
775636Sgblack@eecs.umich.edu        typedef std::list<Target>::iterator Iterator;
785636Sgblack@eecs.umich.edu        typedef std::list<Target>::const_iterator ConstIterator;
795636Sgblack@eecs.umich.edu
809808Sstever@gmail.com      public:
815642Sgblack@eecs.umich.edu        bool needsExclusive;
825636Sgblack@eecs.umich.edu        bool hasUpgrade;
835636Sgblack@eecs.umich.edu
8411175Sandreas.hansson@arm.com        TargetList();
855390SN/A        void resetFlags() { needsExclusive = hasUpgrade = false; }
8611175Sandreas.hansson@arm.com        bool isReset()    { return !needsExclusive && !hasUpgrade; }
875636Sgblack@eecs.umich.edu        void add(PacketPtr pkt, Tick readyTime, Counter order,
885636Sgblack@eecs.umich.edu                 bool cpuSide, bool markPending);
895636Sgblack@eecs.umich.edu        void replaceUpgrades();
905636Sgblack@eecs.umich.edu        void clearDownstreamPending();
915636Sgblack@eecs.umich.edu        bool checkFunctional(PacketPtr pkt);
925636Sgblack@eecs.umich.edu        void print(std::ostream &os, int verbosity,
935636Sgblack@eecs.umich.edu                   const std::string &prefix) const;
945636Sgblack@eecs.umich.edu    };
955636Sgblack@eecs.umich.edu
965636Sgblack@eecs.umich.edu    /** A list of MSHRs. */
975636Sgblack@eecs.umich.edu    typedef std::list<MSHR *> List;
985636Sgblack@eecs.umich.edu    /** MSHR list iterator. */
995636Sgblack@eecs.umich.edu    typedef List::iterator Iterator;
1005636Sgblack@eecs.umich.edu    /** MSHR list const_iterator. */
1015636Sgblack@eecs.umich.edu    typedef List::const_iterator ConstIterator;
1025636Sgblack@eecs.umich.edu
1035636Sgblack@eecs.umich.edu    /** Pointer to queue containing this MSHR. */
1045636Sgblack@eecs.umich.edu    MSHRQueue *queue;
1055636Sgblack@eecs.umich.edu
1065636Sgblack@eecs.umich.edu    /** Cycle when ready to issue */
1075636Sgblack@eecs.umich.edu    Tick readyTime;
1085636Sgblack@eecs.umich.edu
1095636Sgblack@eecs.umich.edu    /** Order number assigned by the miss queue. */
1105636Sgblack@eecs.umich.edu    Counter order;
1117903Shestness@cs.utexas.edu
11211168Sandreas.hansson@arm.com    /** Address of the request. */
11311168Sandreas.hansson@arm.com    Addr addr;
11410905Sandreas.sandberg@arm.com
11511175Sandreas.hansson@arm.com    /** Size of the request. */
1167903Shestness@cs.utexas.edu    int size;
1175390SN/A
1185390SN/A    /** True if the request has been sent to the bus. */
1197811Ssteve.reinhardt@amd.com    bool inService;
1205390SN/A
1215390SN/A    /** True if we will be putting the returned block in the cache */
122    bool isCacheFill;
123
124    /** True if we need to get an exclusive copy of the block. */
125    bool needsExclusive() const { return targets->needsExclusive; }
126
127    /** True if the request is uncacheable */
128    bool _isUncacheable;
129
130    bool downstreamPending;
131
132    bool pendingInvalidate;
133    bool pendingShared;
134
135    /** Thread number of the miss. */
136    short threadNum;
137    /** The number of currently allocated targets. */
138    short ntargets;
139
140
141    /** Data buffer (if needed).  Currently used only for pending
142     * upgrade handling. */
143    uint8_t *data;
144
145    /**
146     * Pointer to this MSHR on the ready list.
147     * @sa MissQueue, MSHRQueue::readyList
148     */
149    Iterator readyIter;
150
151    /**
152     * Pointer to this MSHR on the allocated list.
153     * @sa MissQueue, MSHRQueue::allocatedList
154     */
155    Iterator allocIter;
156
157private:
158    /** List of all requests that match the address */
159    TargetList *targets;
160
161    TargetList *deferredTargets;
162
163public:
164
165    bool isUncacheable() { return _isUncacheable; }
166
167    /**
168     * Allocate a miss to this MSHR.
169     * @param cmd The requesting command.
170     * @param addr The address of the miss.
171     * @param asid The address space id of the miss.
172     * @param size The number of bytes to request.
173     * @param pkt  The original miss.
174     */
175    void allocate(Addr addr, int size, PacketPtr pkt,
176                  Tick when, Counter _order);
177
178    bool markInService();
179
180    void clearDownstreamPending();
181
182    /**
183     * Mark this MSHR as free.
184     */
185    void deallocate();
186
187    /**
188     * Add a request to the list of targets.
189     * @param target The target.
190     */
191    void allocateTarget(PacketPtr target, Tick when, Counter order);
192    bool handleSnoop(PacketPtr target, Counter order);
193
194    /** A simple constructor. */
195    MSHR();
196    /** A simple destructor. */
197    ~MSHR();
198
199    /**
200     * Returns the current number of allocated targets.
201     * @return The current number of allocated targets.
202     */
203    int getNumTargets() { return ntargets; }
204
205    /**
206     * Returns a pointer to the target list.
207     * @return a pointer to the target list.
208     */
209    TargetList *getTargetList() { return targets; }
210
211    /**
212     * Returns true if there are targets left.
213     * @return true if there are targets
214     */
215    bool hasTargets() { return !targets->empty(); }
216
217    /**
218     * Returns a reference to the first target.
219     * @return A pointer to the first target.
220     */
221    Target *getTarget() { assert(hasTargets());  return &targets->front(); }
222
223    /**
224     * Pop first target.
225     */
226    void popTarget()
227    {
228        --ntargets;
229        targets->pop_front();
230    }
231
232    bool isSimpleForward()
233    {
234        if (getNumTargets() != 1)
235            return false;
236        Target *tgt = getTarget();
237        return tgt->isCpuSide() && !tgt->pkt->needsResponse();
238    }
239
240    bool promoteDeferredTargets();
241
242    void handleFill(Packet *pkt, CacheBlk *blk);
243
244    bool checkFunctional(PacketPtr pkt);
245
246    /**
247     * Prints the contents of this MSHR for debugging.
248     */
249    void print(std::ostream &os,
250               int verbosity = 0,
251               const std::string &prefix = "") const;
252};
253
254#endif //__MSHR_HH__
255