mshr_queue.hh revision 11197
12810Srdreslin@umich.edu/*
211051Sandreas.hansson@arm.com * Copyright (c) 2012-2013, 2015 ARM Limited
311051Sandreas.hansson@arm.com * All rights reserved.
411051Sandreas.hansson@arm.com *
511051Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
611051Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
711051Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
811051Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
911051Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
1011051Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
1111051Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
1211051Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
1311051Sandreas.hansson@arm.com *
1411051Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
1511051Sandreas.hansson@arm.com * All rights reserved.
162810Srdreslin@umich.edu *
172810Srdreslin@umich.edu * Redistribution and use in source and binary forms, with or without
182810Srdreslin@umich.edu * modification, are permitted provided that the following conditions are
192810Srdreslin@umich.edu * met: redistributions of source code must retain the above copyright
202810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer;
212810Srdreslin@umich.edu * redistributions in binary form must reproduce the above copyright
222810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer in the
232810Srdreslin@umich.edu * documentation and/or other materials provided with the distribution;
242810Srdreslin@umich.edu * neither the name of the copyright holders nor the names of its
252810Srdreslin@umich.edu * contributors may be used to endorse or promote products derived from
262810Srdreslin@umich.edu * this software without specific prior written permission.
272810Srdreslin@umich.edu *
282810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392810Srdreslin@umich.edu *
402810Srdreslin@umich.edu * Authors: Erik Hallnor
412810Srdreslin@umich.edu *          Andreas Sandberg
4211051Sandreas.hansson@arm.com */
4311051Sandreas.hansson@arm.com
442810Srdreslin@umich.edu/** @file
4511051Sandreas.hansson@arm.com * Declaration of a structure to manage MSHRs.
4611051Sandreas.hansson@arm.com */
472810Srdreslin@umich.edu
482810Srdreslin@umich.edu#ifndef __MEM_CACHE_MSHR_QUEUE_HH__
492810Srdreslin@umich.edu#define __MEM_CACHE_MSHR_QUEUE_HH__
502810Srdreslin@umich.edu
5111051Sandreas.hansson@arm.com#include <vector>
522810Srdreslin@umich.edu
532810Srdreslin@umich.edu#include "mem/cache/mshr.hh"
5411051Sandreas.hansson@arm.com#include "mem/packet.hh"
552810Srdreslin@umich.edu#include "sim/drain.hh"
5611051Sandreas.hansson@arm.com
5711051Sandreas.hansson@arm.com/**
5811051Sandreas.hansson@arm.com * A Class for maintaining a list of pending and allocated memory requests.
5911051Sandreas.hansson@arm.com */
6011051Sandreas.hansson@arm.comclass MSHRQueue : public Drainable
6111051Sandreas.hansson@arm.com{
6211051Sandreas.hansson@arm.com  private:
6311051Sandreas.hansson@arm.com    /** Local label (for functional print requests) */
6411051Sandreas.hansson@arm.com    const std::string label;
6511051Sandreas.hansson@arm.com
6611053Sandreas.hansson@arm.com    // Parameters
6711053Sandreas.hansson@arm.com    /**
6811051Sandreas.hansson@arm.com     * The total number of entries in this queue. This number is set as the
6911051Sandreas.hansson@arm.com     * number of entries requested plus (numReserve - 1). This allows for
7011051Sandreas.hansson@arm.com     * the same number of effective entries while still maintaining the reserve.
7111197Sandreas.hansson@arm.com     */
7211197Sandreas.hansson@arm.com    const int numEntries;
7311199Sandreas.hansson@arm.com
7411197Sandreas.hansson@arm.com    /**
7511197Sandreas.hansson@arm.com     * The number of entries to hold in reserve. This is needed because copy
7611197Sandreas.hansson@arm.com     * operations can allocate upto 4 entries at one time.
7711051Sandreas.hansson@arm.com     */
7811051Sandreas.hansson@arm.com    const int numReserve;
7911051Sandreas.hansson@arm.com
8011051Sandreas.hansson@arm.com    /**
8111051Sandreas.hansson@arm.com     * The number of entries to reserve for future demand accesses.
8211051Sandreas.hansson@arm.com     * Prevent prefetcher from taking all mshr entries
8311051Sandreas.hansson@arm.com     */
8411051Sandreas.hansson@arm.com    const int demandReserve;
8511051Sandreas.hansson@arm.com
8611051Sandreas.hansson@arm.com    /**  MSHR storage. */
8711051Sandreas.hansson@arm.com    std::vector<MSHR> registers;
8811051Sandreas.hansson@arm.com    /** Holds pointers to all allocated entries. */
8911051Sandreas.hansson@arm.com    MSHR::List allocatedList;
9011051Sandreas.hansson@arm.com    /** Holds pointers to entries that haven't been sent to the bus. */
9111051Sandreas.hansson@arm.com    MSHR::List readyList;
9211051Sandreas.hansson@arm.com    /** Holds non allocated entries. */
9311051Sandreas.hansson@arm.com    MSHR::List freeList;
9411051Sandreas.hansson@arm.com
9511051Sandreas.hansson@arm.com    MSHR::Iterator addToReadyList(MSHR *mshr);
9611051Sandreas.hansson@arm.com
9711051Sandreas.hansson@arm.com
9811051Sandreas.hansson@arm.com  public:
9911051Sandreas.hansson@arm.com    /** The number of allocated entries. */
10011051Sandreas.hansson@arm.com    int allocated;
10111051Sandreas.hansson@arm.com    /** The number of entries that have been forwarded to the bus. */
10211051Sandreas.hansson@arm.com    int inServiceEntries;
10311051Sandreas.hansson@arm.com    /** The index of this queue within the cache (MSHR queue vs. write
10411051Sandreas.hansson@arm.com     * buffer). */
10511051Sandreas.hansson@arm.com    const int index;
10611051Sandreas.hansson@arm.com
10711051Sandreas.hansson@arm.com    /**
10811051Sandreas.hansson@arm.com     * Create a queue with a given number of entries.
10911051Sandreas.hansson@arm.com     * @param num_entrys The number of entries in this queue.
11011051Sandreas.hansson@arm.com     * @param reserve The minimum number of entries needed to satisfy
11111051Sandreas.hansson@arm.com     * any access.
11211051Sandreas.hansson@arm.com     * @param demand_reserve The minimum number of entries needed to satisfy
11311051Sandreas.hansson@arm.com     * demand accesses.
11411051Sandreas.hansson@arm.com     */
11511051Sandreas.hansson@arm.com    MSHRQueue(const std::string &_label, int num_entries, int reserve,
11611051Sandreas.hansson@arm.com              int demand_reserve, int index);
11711051Sandreas.hansson@arm.com
11811051Sandreas.hansson@arm.com    /**
11911051Sandreas.hansson@arm.com     * Find the first MSHR that matches the provided address.
12011051Sandreas.hansson@arm.com     * @param blk_addr The block address to find.
12111051Sandreas.hansson@arm.com     * @param is_secure True if the target memory space is secure.
12211051Sandreas.hansson@arm.com     * @return Pointer to the matching MSHR, null if not found.
12311051Sandreas.hansson@arm.com     */
12411051Sandreas.hansson@arm.com    MSHR *findMatch(Addr blk_addr, bool is_secure) const;
12511051Sandreas.hansson@arm.com
12611051Sandreas.hansson@arm.com    /**
12711051Sandreas.hansson@arm.com     * Find and return all the matching entries in the provided vector.
12811051Sandreas.hansson@arm.com     * @param blk_addr The block  address to find.
12911051Sandreas.hansson@arm.com     * @param is_secure True if the target memory space is secure.
13011051Sandreas.hansson@arm.com     * @param matches The vector to return pointers to the matching entries.
13111051Sandreas.hansson@arm.com     * @return True if any matches are found, false otherwise.
13211051Sandreas.hansson@arm.com     */
13311051Sandreas.hansson@arm.com    bool findMatches(Addr blk_addr, bool is_secure,
13411051Sandreas.hansson@arm.com                     std::vector<MSHR*>& matches) const;
13511051Sandreas.hansson@arm.com
13611051Sandreas.hansson@arm.com    /**
13711051Sandreas.hansson@arm.com     * Find any pending requests that overlap the given request.
13811051Sandreas.hansson@arm.com     * @param blk_addr Block address.
13911051Sandreas.hansson@arm.com     * @param is_secure True if the target memory space is secure.
14011051Sandreas.hansson@arm.com     * @return A pointer to the earliest matching MSHR.
14111051Sandreas.hansson@arm.com     */
14211051Sandreas.hansson@arm.com    MSHR *findPending(Addr blk_addr, bool is_secure) const;
14311051Sandreas.hansson@arm.com
14411051Sandreas.hansson@arm.com    bool checkFunctional(PacketPtr pkt, Addr blk_addr);
14511051Sandreas.hansson@arm.com
14611051Sandreas.hansson@arm.com    /**
14711051Sandreas.hansson@arm.com     * Allocates a new MSHR for the request and size. This places the request
14811051Sandreas.hansson@arm.com     * as the first target in the MSHR.
14911051Sandreas.hansson@arm.com     *
15011051Sandreas.hansson@arm.com     * @param blk_addr The address of the block.
15111051Sandreas.hansson@arm.com     * @param blk_size The number of bytes to request.
15211051Sandreas.hansson@arm.com     * @param pkt The original miss.
15311051Sandreas.hansson@arm.com     * @param when_ready When should the MSHR be ready to act upon.
15411051Sandreas.hansson@arm.com     * @param order The logical order of this MSHR
15511051Sandreas.hansson@arm.com     * @param alloc_on_fill Should the cache allocate a block on fill
15611051Sandreas.hansson@arm.com     *
15711051Sandreas.hansson@arm.com     * @return The a pointer to the MSHR allocated.
15811051Sandreas.hansson@arm.com     *
15911051Sandreas.hansson@arm.com     * @pre There are free entries.
16011051Sandreas.hansson@arm.com     */
16111051Sandreas.hansson@arm.com    MSHR *allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
16211051Sandreas.hansson@arm.com                   Tick when_ready, Counter order, bool alloc_on_fill);
16311051Sandreas.hansson@arm.com
16411051Sandreas.hansson@arm.com    /**
16511051Sandreas.hansson@arm.com     * Removes the given MSHR from the queue. This places the MSHR on the
16611051Sandreas.hansson@arm.com     * free list.
16711051Sandreas.hansson@arm.com     * @param mshr
16811051Sandreas.hansson@arm.com     */
16911051Sandreas.hansson@arm.com    void deallocate(MSHR *mshr);
17011051Sandreas.hansson@arm.com
17111051Sandreas.hansson@arm.com    /**
17211051Sandreas.hansson@arm.com     * Remove a MSHR from the queue. Returns an iterator into the
17311051Sandreas.hansson@arm.com     * allocatedList for faster squash implementation.
17411051Sandreas.hansson@arm.com     * @param mshr The MSHR to remove.
17511051Sandreas.hansson@arm.com     * @return An iterator to the next entry in the allocatedList.
17611051Sandreas.hansson@arm.com     */
17711051Sandreas.hansson@arm.com    MSHR::Iterator deallocateOne(MSHR *mshr);
17811051Sandreas.hansson@arm.com
17911051Sandreas.hansson@arm.com    /**
18011051Sandreas.hansson@arm.com     * Moves the MSHR to the front of the pending list if it is not
18111051Sandreas.hansson@arm.com     * in service.
18211051Sandreas.hansson@arm.com     * @param mshr The entry to move.
18311051Sandreas.hansson@arm.com     */
18411051Sandreas.hansson@arm.com    void moveToFront(MSHR *mshr);
18511051Sandreas.hansson@arm.com
18611051Sandreas.hansson@arm.com    /**
18711051Sandreas.hansson@arm.com     * Mark the given MSHR as in service. This removes the MSHR from the
18811051Sandreas.hansson@arm.com     * readyList or deallocates the MSHR if it does not expect a response.
18911051Sandreas.hansson@arm.com     *
19011051Sandreas.hansson@arm.com     * @param mshr The MSHR to mark in service.
19111051Sandreas.hansson@arm.com     * @param pending_dirty_resp Whether we expect a dirty response
19211051Sandreas.hansson@arm.com     *                           from another cache
19311051Sandreas.hansson@arm.com     */
19411051Sandreas.hansson@arm.com    void markInService(MSHR *mshr, bool pending_dirty_resp);
19511051Sandreas.hansson@arm.com
19611051Sandreas.hansson@arm.com    /**
19711051Sandreas.hansson@arm.com     * Mark an in service entry as pending, used to resend a request.
19811051Sandreas.hansson@arm.com     * @param mshr The MSHR to resend.
19911051Sandreas.hansson@arm.com     */
20011051Sandreas.hansson@arm.com    void markPending(MSHR *mshr);
20111051Sandreas.hansson@arm.com
20211051Sandreas.hansson@arm.com    /**
20311051Sandreas.hansson@arm.com     * Squash outstanding requests with the given thread number. If a request
20411051Sandreas.hansson@arm.com     * is in service, just squashes the targets.
20511051Sandreas.hansson@arm.com     * @param threadNum The thread to squash.
20611197Sandreas.hansson@arm.com     */
20711197Sandreas.hansson@arm.com    void squash(int threadNum);
20811197Sandreas.hansson@arm.com
20911197Sandreas.hansson@arm.com    /**
21011051Sandreas.hansson@arm.com     * Deallocate top target, possibly freeing the MSHR
21111051Sandreas.hansson@arm.com     * @return if MSHR queue is no longer full
21211051Sandreas.hansson@arm.com     */
21311051Sandreas.hansson@arm.com    bool forceDeallocateTarget(MSHR *mshr);
21411051Sandreas.hansson@arm.com
21511051Sandreas.hansson@arm.com    /**
21611051Sandreas.hansson@arm.com     * Returns true if the pending list is not empty.
21711051Sandreas.hansson@arm.com     * @return True if there are outstanding requests.
21811051Sandreas.hansson@arm.com     */
21911051Sandreas.hansson@arm.com    bool havePending() const
22011051Sandreas.hansson@arm.com    {
22111051Sandreas.hansson@arm.com        return !readyList.empty();
22211051Sandreas.hansson@arm.com    }
22311051Sandreas.hansson@arm.com
22411051Sandreas.hansson@arm.com    /**
22511051Sandreas.hansson@arm.com     * Returns true if there are no free entries.
22611051Sandreas.hansson@arm.com     * @return True if this queue is full.
22711051Sandreas.hansson@arm.com     */
22811197Sandreas.hansson@arm.com    bool isFull() const
22911197Sandreas.hansson@arm.com    {
23011051Sandreas.hansson@arm.com        return (allocated > numEntries - numReserve);
23111197Sandreas.hansson@arm.com    }
23211197Sandreas.hansson@arm.com
23311197Sandreas.hansson@arm.com    /**
23411197Sandreas.hansson@arm.com     * Returns true if sufficient mshrs for prefetch.
23511197Sandreas.hansson@arm.com     * @return True if sufficient mshrs for prefetch.
23611197Sandreas.hansson@arm.com     */
23711197Sandreas.hansson@arm.com    bool canPrefetch() const
23811197Sandreas.hansson@arm.com    {
23911197Sandreas.hansson@arm.com        return (allocated < numEntries - (numReserve + demandReserve));
24011197Sandreas.hansson@arm.com    }
24111197Sandreas.hansson@arm.com
24211197Sandreas.hansson@arm.com    /**
24311197Sandreas.hansson@arm.com     * Returns the MSHR at the head of the readyList.
24411197Sandreas.hansson@arm.com     * @return The next request to service.
24511051Sandreas.hansson@arm.com     */
24611197Sandreas.hansson@arm.com    MSHR *getNextMSHR() const
24711197Sandreas.hansson@arm.com    {
24811197Sandreas.hansson@arm.com        if (readyList.empty() || readyList.front()->readyTime > curTick()) {
24911197Sandreas.hansson@arm.com            return NULL;
25011197Sandreas.hansson@arm.com        }
25111197Sandreas.hansson@arm.com        return readyList.front();
25211051Sandreas.hansson@arm.com    }
25311051Sandreas.hansson@arm.com
25411051Sandreas.hansson@arm.com    Tick nextMSHRReadyTime() const
25511051Sandreas.hansson@arm.com    {
25611051Sandreas.hansson@arm.com        return readyList.empty() ? MaxTick : readyList.front()->readyTime;
25711051Sandreas.hansson@arm.com    }
25811051Sandreas.hansson@arm.com
25911051Sandreas.hansson@arm.com    DrainState drain() override;
26011051Sandreas.hansson@arm.com};
26111051Sandreas.hansson@arm.com
26211051Sandreas.hansson@arm.com#endif //__MEM_CACHE_MSHR_QUEUE_HH__
26311051Sandreas.hansson@arm.com