mshr.hh revision 11375
12810SN/A/*
211375Sandreas.hansson@arm.com * Copyright (c) 2012-2013, 2015-2016 ARM Limited
39663Suri.wiener@arm.com * All rights reserved.
49663Suri.wiener@arm.com *
59663Suri.wiener@arm.com * The license below extends only to copyright in the software and shall
69663Suri.wiener@arm.com * not be construed as granting a license to any other intellectual
79663Suri.wiener@arm.com * property including but not limited to intellectual property relating
89663Suri.wiener@arm.com * to a hardware implementation of the functionality of the software
99663Suri.wiener@arm.com * licensed hereunder.  You may use the software subject to the license
109663Suri.wiener@arm.com * terms below provided that you ensure that this notice is replicated
119663Suri.wiener@arm.com * unmodified and in its entirety in all distributions of the software,
129663Suri.wiener@arm.com * modified or unmodified, in source code or in binary form.
139663Suri.wiener@arm.com *
142810SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152810SN/A * All rights reserved.
162810SN/A *
172810SN/A * Redistribution and use in source and binary forms, with or without
182810SN/A * modification, are permitted provided that the following conditions are
192810SN/A * met: redistributions of source code must retain the above copyright
202810SN/A * notice, this list of conditions and the following disclaimer;
212810SN/A * redistributions in binary form must reproduce the above copyright
222810SN/A * notice, this list of conditions and the following disclaimer in the
232810SN/A * documentation and/or other materials provided with the distribution;
242810SN/A * neither the name of the copyright holders nor the names of its
252810SN/A * contributors may be used to endorse or promote products derived from
262810SN/A * this software without specific prior written permission.
272810SN/A *
282810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392810SN/A *
402810SN/A * Authors: Erik Hallnor
412810SN/A */
422810SN/A
432810SN/A/**
442810SN/A * @file
452810SN/A * Miss Status and Handling Register (MSHR) declaration.
462810SN/A */
472810SN/A
4810764Sandreas.hansson@arm.com#ifndef __MEM_CACHE_MSHR_HH__
4910764Sandreas.hansson@arm.com#define __MEM_CACHE_MSHR_HH__
502810SN/A
514626SN/A#include <list>
524626SN/A
535314SN/A#include "base/printable.hh"
5411375Sandreas.hansson@arm.com#include "mem/cache/queue_entry.hh"
552810SN/A
5611375Sandreas.hansson@arm.comclass Cache;
572810SN/A
582810SN/A/**
592810SN/A * Miss Status and handling Register. This class keeps all the information
603374SN/A * needed to handle a cache miss including a list of target requests.
619264Sdjordje.kovacevic@arm.com * @sa  \ref gem5MemorySystem "gem5 Memory System"
622810SN/A */
6311375Sandreas.hansson@arm.comclass MSHR : public QueueEntry, public Printable
644626SN/A{
654626SN/A
669725Sandreas.hansson@arm.com    /**
6711375Sandreas.hansson@arm.com     * Consider the queues friends to avoid making everything public.
689725Sandreas.hansson@arm.com     */
6911375Sandreas.hansson@arm.com    template<typename Entry>
7011375Sandreas.hansson@arm.com    friend class Queue;
719725Sandreas.hansson@arm.com    friend class MSHRQueue;
729725Sandreas.hansson@arm.com
739725Sandreas.hansson@arm.com  private:
749725Sandreas.hansson@arm.com
759725Sandreas.hansson@arm.com    /** Flag set by downstream caches */
769725Sandreas.hansson@arm.com    bool downstreamPending;
779725Sandreas.hansson@arm.com
7811284Sandreas.hansson@arm.com    /**
7911284Sandreas.hansson@arm.com     * Here we use one flag to track both if:
8011284Sandreas.hansson@arm.com     *
8111284Sandreas.hansson@arm.com     * 1. We are going to become owner or not, i.e., we will get the
8211284Sandreas.hansson@arm.com     * block in an ownership state (Owned or Modified) with BlkDirty
8311284Sandreas.hansson@arm.com     * set. This determines whether or not we are going to become the
8411284Sandreas.hansson@arm.com     * responder and ordering point for future requests that we snoop.
8511284Sandreas.hansson@arm.com     *
8611284Sandreas.hansson@arm.com     * 2. We know that we are going to get a writable block, i.e. we
8711284Sandreas.hansson@arm.com     * will get the block in writable state (Exclusive or Modified
8811284Sandreas.hansson@arm.com     * state) with BlkWritable set. That determines whether additional
8911284Sandreas.hansson@arm.com     * targets with needsWritable set will be able to be satisfied, or
9011284Sandreas.hansson@arm.com     * if not should be put on the deferred list to possibly wait for
9111284Sandreas.hansson@arm.com     * another request that does give us writable access.
9211284Sandreas.hansson@arm.com     *
9311284Sandreas.hansson@arm.com     * Condition 2 is actually just a shortcut that saves us from
9411284Sandreas.hansson@arm.com     * possibly building a deferred target list and calling
9511284Sandreas.hansson@arm.com     * promoteWritable() every time we get a writable block. Condition
9611284Sandreas.hansson@arm.com     * 1, tracking ownership, is what is important. However, we never
9711284Sandreas.hansson@arm.com     * receive ownership without marking the block dirty, and
9811284Sandreas.hansson@arm.com     * consequently use pendingModified to track both ownership and
9911284Sandreas.hansson@arm.com     * writability rather than having separate pendingDirty and
10011284Sandreas.hansson@arm.com     * pendingWritable flags.
10111284Sandreas.hansson@arm.com     */
10211284Sandreas.hansson@arm.com    bool pendingModified;
1039725Sandreas.hansson@arm.com
1049725Sandreas.hansson@arm.com    /** Did we snoop an invalidate while waiting for data? */
1059725Sandreas.hansson@arm.com    bool postInvalidate;
1069725Sandreas.hansson@arm.com
1079725Sandreas.hansson@arm.com    /** Did we snoop a read while waiting for data? */
1089725Sandreas.hansson@arm.com    bool postDowngrade;
1099725Sandreas.hansson@arm.com
1102810SN/A  public:
1114626SN/A
11211375Sandreas.hansson@arm.com    /** True if the entry is just a simple forward from an upper level */
11311375Sandreas.hansson@arm.com    bool isForward;
11411375Sandreas.hansson@arm.com
1154626SN/A    class Target {
1164626SN/A      public:
1175875Ssteve.reinhardt@amd.com
1185875Ssteve.reinhardt@amd.com        enum Source {
1195875Ssteve.reinhardt@amd.com            FromCPU,
1205875Ssteve.reinhardt@amd.com            FromSnoop,
1215875Ssteve.reinhardt@amd.com            FromPrefetcher
1225875Ssteve.reinhardt@amd.com        };
1235875Ssteve.reinhardt@amd.com
12410766Sandreas.hansson@arm.com        const Tick recvTime;  //!< Time when request was received (for stats)
12510766Sandreas.hansson@arm.com        const Tick readyTime; //!< Time when request is ready to be serviced
12610766Sandreas.hansson@arm.com        const Counter order;  //!< Global order (for memory consistency mgmt)
12710766Sandreas.hansson@arm.com        const PacketPtr pkt;  //!< Pending request packet.
12810766Sandreas.hansson@arm.com        const Source source;  //!< Request from cpu, memory, or prefetcher?
12910766Sandreas.hansson@arm.com        const bool markedPending; //!< Did we mark upstream MSHR
13010766Sandreas.hansson@arm.com                                  //!< as downstreamPending?
1314626SN/A
1325318SN/A        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
1335875Ssteve.reinhardt@amd.com               Source _source, bool _markedPending)
1347823Ssteve.reinhardt@amd.com            : recvTime(curTick()), readyTime(_readyTime), order(_order),
1355875Ssteve.reinhardt@amd.com              pkt(_pkt), source(_source), markedPending(_markedPending)
1364626SN/A        {}
1374626SN/A    };
1384626SN/A
1394903SN/A    class TargetList : public std::list<Target> {
1404903SN/A
1414903SN/A      public:
14211284Sandreas.hansson@arm.com        bool needsWritable;
1434903SN/A        bool hasUpgrade;
1444903SN/A
1454903SN/A        TargetList();
14611284Sandreas.hansson@arm.com        void resetFlags() { needsWritable = hasUpgrade = false; }
14711284Sandreas.hansson@arm.com        bool isReset() const { return !needsWritable && !hasUpgrade; }
1485318SN/A        void add(PacketPtr pkt, Tick readyTime, Counter order,
1495875Ssteve.reinhardt@amd.com                 Target::Source source, bool markPending);
15011357Sstephan.diestelhorst@arm.com
15111357Sstephan.diestelhorst@arm.com        /**
15211357Sstephan.diestelhorst@arm.com         * Convert upgrades to the equivalent request if the cache line they
15311357Sstephan.diestelhorst@arm.com         * refer to would have been invalid (Upgrade -> ReadEx, SC* -> Fail).
15411357Sstephan.diestelhorst@arm.com         * Used to rejig ordering between targets waiting on an MSHR. */
1554903SN/A        void replaceUpgrades();
15611357Sstephan.diestelhorst@arm.com
1574908SN/A        void clearDownstreamPending();
1584920SN/A        bool checkFunctional(PacketPtr pkt);
1595314SN/A        void print(std::ostream &os, int verbosity,
1605314SN/A                   const std::string &prefix) const;
1614903SN/A    };
1624903SN/A
1632810SN/A    /** A list of MSHRs. */
1642810SN/A    typedef std::list<MSHR *> List;
1652810SN/A    /** MSHR list iterator. */
1662810SN/A    typedef List::iterator Iterator;
1674903SN/A
16811197Sandreas.hansson@arm.com    /** Keep track of whether we should allocate on fill or not */
16911197Sandreas.hansson@arm.com    bool allocOnFill;
17011197Sandreas.hansson@arm.com
1717667Ssteve.reinhardt@amd.com    /** The pending* and post* flags are only valid if inService is
1727667Ssteve.reinhardt@amd.com     *  true.  Using the accessor functions lets us detect if these
1737667Ssteve.reinhardt@amd.com     *  flags are accessed improperly.
1747667Ssteve.reinhardt@amd.com     */
1757667Ssteve.reinhardt@amd.com
17611284Sandreas.hansson@arm.com    /** True if we need to get a writable copy of the block. */
17711284Sandreas.hansson@arm.com    bool needsWritable() const { return targets.needsWritable; }
1789725Sandreas.hansson@arm.com
17911284Sandreas.hansson@arm.com    bool isPendingModified() const {
18011284Sandreas.hansson@arm.com        assert(inService); return pendingModified;
1817667Ssteve.reinhardt@amd.com    }
1827667Ssteve.reinhardt@amd.com
1837667Ssteve.reinhardt@amd.com    bool hasPostInvalidate() const {
1847667Ssteve.reinhardt@amd.com        assert(inService); return postInvalidate;
1857667Ssteve.reinhardt@amd.com    }
1867667Ssteve.reinhardt@amd.com
1877667Ssteve.reinhardt@amd.com    bool hasPostDowngrade() const {
1887667Ssteve.reinhardt@amd.com        assert(inService); return postDowngrade;
1897667Ssteve.reinhardt@amd.com    }
1904665SN/A
19111375Sandreas.hansson@arm.com    bool sendPacket(Cache &cache);
19211375Sandreas.hansson@arm.com
1939725Sandreas.hansson@arm.com  private:
1944668SN/A
1952810SN/A    /**
1962810SN/A     * Pointer to this MSHR on the ready list.
1972810SN/A     * @sa MissQueue, MSHRQueue::readyList
1982810SN/A     */
1992810SN/A    Iterator readyIter;
2004626SN/A
2012810SN/A    /**
2022810SN/A     * Pointer to this MSHR on the allocated list.
2032810SN/A     * @sa MissQueue, MSHRQueue::allocatedList
2042810SN/A     */
2052810SN/A    Iterator allocIter;
2062810SN/A
2073374SN/A    /** List of all requests that match the address */
2089725Sandreas.hansson@arm.com    TargetList targets;
2092810SN/A
2109725Sandreas.hansson@arm.com    TargetList deferredTargets;
2114665SN/A
2129725Sandreas.hansson@arm.com  public:
2134626SN/A
2142810SN/A    /**
2152810SN/A     * Allocate a miss to this MSHR.
21610764Sandreas.hansson@arm.com     * @param blk_addr The address of the block.
21710764Sandreas.hansson@arm.com     * @param blk_size The number of bytes to request.
21810764Sandreas.hansson@arm.com     * @param pkt The original miss.
21910764Sandreas.hansson@arm.com     * @param when_ready When should the MSHR be ready to act upon.
22010764Sandreas.hansson@arm.com     * @param _order The logical order of this MSHR
22111197Sandreas.hansson@arm.com     * @param alloc_on_fill Should the cache allocate a block on fill
2222810SN/A     */
22310764Sandreas.hansson@arm.com    void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
22411197Sandreas.hansson@arm.com                  Tick when_ready, Counter _order, bool alloc_on_fill);
2252810SN/A
22611375Sandreas.hansson@arm.com    void markInService(bool pending_modified_resp);
2274908SN/A
2285318SN/A    void clearDownstreamPending();
2295318SN/A
2302810SN/A    /**
2312810SN/A     * Mark this MSHR as free.
2322810SN/A     */
2332810SN/A    void deallocate();
2342810SN/A
2352810SN/A    /**
2363374SN/A     * Add a request to the list of targets.
2372810SN/A     * @param target The target.
2382810SN/A     */
23911197Sandreas.hansson@arm.com    void allocateTarget(PacketPtr target, Tick when, Counter order,
24011197Sandreas.hansson@arm.com                        bool alloc_on_fill);
2414902SN/A    bool handleSnoop(PacketPtr target, Counter order);
2422810SN/A
2432810SN/A    /** A simple constructor. */
2442810SN/A    MSHR();
2452810SN/A
2462810SN/A    /**
2472810SN/A     * Returns the current number of allocated targets.
2482810SN/A     * @return The current number of allocated targets.
2492810SN/A     */
2509725Sandreas.hansson@arm.com    int getNumTargets() const
2519725Sandreas.hansson@arm.com    { return targets.size() + deferredTargets.size(); }
2522810SN/A
2532810SN/A    /**
2544899SN/A     * Returns true if there are targets left.
2554899SN/A     * @return true if there are targets
2564899SN/A     */
2579725Sandreas.hansson@arm.com    bool hasTargets() const { return !targets.empty(); }
2584899SN/A
2594899SN/A    /**
2602810SN/A     * Returns a reference to the first target.
2612810SN/A     * @return A pointer to the first target.
2622810SN/A     */
2639725Sandreas.hansson@arm.com    Target *getTarget()
2645730SSteve.Reinhardt@amd.com    {
2655730SSteve.Reinhardt@amd.com        assert(hasTargets());
2669725Sandreas.hansson@arm.com        return &targets.front();
2675730SSteve.Reinhardt@amd.com    }
2682810SN/A
2692810SN/A    /**
2702810SN/A     * Pop first target.
2712810SN/A     */
2722810SN/A    void popTarget()
2732810SN/A    {
2749725Sandreas.hansson@arm.com        targets.pop_front();
2752810SN/A    }
2762810SN/A
2774665SN/A    bool promoteDeferredTargets();
2784665SN/A
27911284Sandreas.hansson@arm.com    void promoteWritable();
2804668SN/A
2815314SN/A    bool checkFunctional(PacketPtr pkt);
2824920SN/A
2832810SN/A    /**
2845314SN/A     * Prints the contents of this MSHR for debugging.
2852810SN/A     */
2865314SN/A    void print(std::ostream &os,
2875314SN/A               int verbosity = 0,
2885314SN/A               const std::string &prefix = "") const;
2899663Suri.wiener@arm.com    /**
2909663Suri.wiener@arm.com     * A no-args wrapper of print(std::ostream...)  meant to be
2919663Suri.wiener@arm.com     * invoked from DPRINTFs avoiding string overheads in fast mode
2929663Suri.wiener@arm.com     *
2939663Suri.wiener@arm.com     * @return string with mshr fields + [deferred]targets
2949663Suri.wiener@arm.com     */
2959663Suri.wiener@arm.com    std::string print() const;
2962810SN/A};
2972810SN/A
29810764Sandreas.hansson@arm.com#endif // __MEM_CACHE_MSHR_HH__
299