diff options
Diffstat (limited to 'src/mem/cache/mshr.hh')
-rw-r--r-- | src/mem/cache/mshr.hh | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh new file mode 100644 index 000000000..fdb0485cb --- /dev/null +++ b/src/mem/cache/mshr.hh @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Erik Hallnor + */ + +/** + * @file + * Miss Status and Handling Register (MSHR) declaration. + */ + +#ifndef __MSHR_HH__ +#define __MSHR_HH__ + +#include <list> + +#include "base/printable.hh" +#include "mem/packet.hh" + +class CacheBlk; +class MSHRQueue; + +/** + * Miss Status and handling Register. This class keeps all the information + * needed to handle a cache miss including a list of target requests. + */ +class MSHR : public Packet::SenderState, public Printable +{ + + public: + + class Target { + public: + Tick recvTime; //!< Time when request was received (for stats) + Tick readyTime; //!< Time when request is ready to be serviced + Counter order; //!< Global order (for memory consistency mgmt) + PacketPtr pkt; //!< Pending request packet. + bool cpuSide; //!< Did request come from cpu side or mem side? + bool markedPending; //!< Did we mark upstream MSHR + //!< as downstreamPending? + + bool isCpuSide() const { return cpuSide; } + + Target(PacketPtr _pkt, Tick _readyTime, Counter _order, + bool _cpuSide, bool _markedPending) + : recvTime(curTick), readyTime(_readyTime), order(_order), + pkt(_pkt), cpuSide(_cpuSide), markedPending(_markedPending) + {} + }; + + class TargetList : public std::list<Target> { + /** Target list iterator. */ + typedef std::list<Target>::iterator Iterator; + typedef std::list<Target>::const_iterator ConstIterator; + + public: + bool needsExclusive; + bool hasUpgrade; + + TargetList(); + void resetFlags() { needsExclusive = hasUpgrade = false; } + bool isReset() { return !needsExclusive && !hasUpgrade; } + void add(PacketPtr pkt, Tick readyTime, Counter order, + bool cpuSide, bool markPending); + void replaceUpgrades(); + void clearDownstreamPending(); + bool checkFunctional(PacketPtr pkt); + void print(std::ostream &os, int verbosity, + const std::string &prefix) const; + }; + + /** A list of MSHRs. */ + typedef std::list<MSHR *> List; + /** MSHR list iterator. */ + typedef List::iterator Iterator; + /** MSHR list const_iterator. */ + typedef List::const_iterator ConstIterator; + + /** Pointer to queue containing this MSHR. */ + MSHRQueue *queue; + + /** Cycle when ready to issue */ + Tick readyTime; + + /** Order number assigned by the miss queue. */ + Counter order; + + /** Address of the request. */ + Addr addr; + + /** Size of the request. */ + int size; + + /** True if the request has been sent to the bus. */ + bool inService; + + /** True if we will be putting the returned block in the cache */ + bool isCacheFill; + + /** True if we need to get an exclusive copy of the block. */ + bool needsExclusive() const { return targets->needsExclusive; } + + /** True if the request is uncacheable */ + bool _isUncacheable; + + bool downstreamPending; + + bool pendingInvalidate; + bool pendingShared; + + /** Thread number of the miss. */ + short threadNum; + /** The number of currently allocated targets. */ + short ntargets; + + + /** Data buffer (if needed). Currently used only for pending + * upgrade handling. */ + uint8_t *data; + + /** + * Pointer to this MSHR on the ready list. + * @sa MissQueue, MSHRQueue::readyList + */ + Iterator readyIter; + + /** + * Pointer to this MSHR on the allocated list. + * @sa MissQueue, MSHRQueue::allocatedList + */ + Iterator allocIter; + +private: + /** List of all requests that match the address */ + TargetList *targets; + + TargetList *deferredTargets; + +public: + + bool isUncacheable() { return _isUncacheable; } + + /** + * Allocate a miss to this MSHR. + * @param cmd The requesting command. + * @param addr The address of the miss. + * @param asid The address space id of the miss. + * @param size The number of bytes to request. + * @param pkt The original miss. + */ + void allocate(Addr addr, int size, PacketPtr pkt, + Tick when, Counter _order); + + bool markInService(); + + void clearDownstreamPending(); + + /** + * Mark this MSHR as free. + */ + void deallocate(); + + /** + * Add a request to the list of targets. + * @param target The target. + */ + void allocateTarget(PacketPtr target, Tick when, Counter order); + bool handleSnoop(PacketPtr target, Counter order); + + /** A simple constructor. */ + MSHR(); + /** A simple destructor. */ + ~MSHR(); + + /** + * Returns the current number of allocated targets. + * @return The current number of allocated targets. + */ + int getNumTargets() { return ntargets; } + + /** + * Returns a pointer to the target list. + * @return a pointer to the target list. + */ + TargetList *getTargetList() { return targets; } + + /** + * Returns true if there are targets left. + * @return true if there are targets + */ + bool hasTargets() { return !targets->empty(); } + + /** + * Returns a reference to the first target. + * @return A pointer to the first target. + */ + Target *getTarget() { assert(hasTargets()); return &targets->front(); } + + /** + * Pop first target. + */ + void popTarget() + { + --ntargets; + targets->pop_front(); + } + + bool isSimpleForward() + { + if (getNumTargets() != 1) + return false; + Target *tgt = getTarget(); + return tgt->isCpuSide() && !tgt->pkt->needsResponse(); + } + + bool promoteDeferredTargets(); + + void handleFill(Packet *pkt, CacheBlk *blk); + + bool checkFunctional(PacketPtr pkt); + + /** + * Prints the contents of this MSHR for debugging. + */ + void print(std::ostream &os, + int verbosity = 0, + const std::string &prefix = "") const; +}; + +#endif //__MSHR_HH__ |