mshr_queue.hh revision 7667:aa8fd8f6a495
19157Sandreas.hansson@arm.com/*
29157Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
39157Sandreas.hansson@arm.com * All rights reserved.
49157Sandreas.hansson@arm.com *
59157Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
69157Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
79157Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
89157Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
99157Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
109157Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
119157Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
129157Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
139157Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
149157Sandreas.hansson@arm.com * this software without specific prior written permission.
159157Sandreas.hansson@arm.com *
169157Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179157Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189157Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199157Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209157Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219157Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229157Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239157Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249157Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259157Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269157Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279157Sandreas.hansson@arm.com *
289157Sandreas.hansson@arm.com * Authors: Erik Hallnor
299157Sandreas.hansson@arm.com */
309157Sandreas.hansson@arm.com
319157Sandreas.hansson@arm.com/** @file
329157Sandreas.hansson@arm.com * Declaration of a structure to manage MSHRs.
339157Sandreas.hansson@arm.com */
349157Sandreas.hansson@arm.com
359157Sandreas.hansson@arm.com#ifndef __MEM__CACHE__MISS__MSHR_QUEUE_HH__
369157Sandreas.hansson@arm.com#define __MEM__CACHE__MISS__MSHR_QUEUE_HH__
379157Sandreas.hansson@arm.com
389157Sandreas.hansson@arm.com#include <vector>
399157Sandreas.hansson@arm.com
409157Sandreas.hansson@arm.com#include "mem/packet.hh"
419157Sandreas.hansson@arm.com#include "mem/cache/mshr.hh"
429157Sandreas.hansson@arm.com
439157Sandreas.hansson@arm.com/**
449157Sandreas.hansson@arm.com * A Class for maintaining a list of pending and allocated memory requests.
459157Sandreas.hansson@arm.com */
469157Sandreas.hansson@arm.comclass MSHRQueue
479157Sandreas.hansson@arm.com{
489157Sandreas.hansson@arm.com  private:
499418Sandreas.hansson@arm.com    /** Local label (for functional print requests) */
509157Sandreas.hansson@arm.com    const std::string label;
519356Snilay@cs.wisc.edu
529157Sandreas.hansson@arm.com    /**  MSHR storage. */
539157Sandreas.hansson@arm.com    MSHR *registers;
549157Sandreas.hansson@arm.com    /** Holds pointers to all allocated entries. */
559157Sandreas.hansson@arm.com    MSHR::List allocatedList;
569157Sandreas.hansson@arm.com    /** Holds pointers to entries that haven't been sent to the bus. */
579157Sandreas.hansson@arm.com    MSHR::List readyList;
589157Sandreas.hansson@arm.com    /** Holds non allocated entries. */
599157Sandreas.hansson@arm.com    MSHR::List freeList;
609157Sandreas.hansson@arm.com
619157Sandreas.hansson@arm.com    // Parameters
629157Sandreas.hansson@arm.com    /**
639179Sandreas.hansson@arm.com     * The total number of entries in this queue. This number is set as the
649179Sandreas.hansson@arm.com     * number of entries requested plus (numReserve - 1). This allows for
659179Sandreas.hansson@arm.com     * the same number of effective entries while still maintaining the reserve.
669179Sandreas.hansson@arm.com     */
679179Sandreas.hansson@arm.com    const int numEntries;
689179Sandreas.hansson@arm.com
699180Sandreas.hansson@arm.com    /**
709179Sandreas.hansson@arm.com     * The number of entries to hold in reserve. This is needed because copy
719157Sandreas.hansson@arm.com     * operations can allocate upto 4 entries at one time.
729157Sandreas.hansson@arm.com     */
739157Sandreas.hansson@arm.com    const int numReserve;
749157Sandreas.hansson@arm.com
759157Sandreas.hansson@arm.com    MSHR::Iterator addToReadyList(MSHR *mshr);
769157Sandreas.hansson@arm.com
779157Sandreas.hansson@arm.com
789179Sandreas.hansson@arm.com  public:
799179Sandreas.hansson@arm.com    /** The number of allocated entries. */
809179Sandreas.hansson@arm.com    int allocated;
819179Sandreas.hansson@arm.com    /** The number of entries that have been forwarded to the bus. */
829179Sandreas.hansson@arm.com    int inServiceEntries;
839179Sandreas.hansson@arm.com    /** The index of this queue within the cache (MSHR queue vs. write
849179Sandreas.hansson@arm.com     * buffer). */
859179Sandreas.hansson@arm.com    const int index;
869179Sandreas.hansson@arm.com
879179Sandreas.hansson@arm.com    /**
889179Sandreas.hansson@arm.com     * Create a queue with a given number of entries.
899179Sandreas.hansson@arm.com     * @param num_entrys The number of entries in this queue.
909179Sandreas.hansson@arm.com     * @param reserve The minimum number of entries needed to satisfy
919179Sandreas.hansson@arm.com     * any access.
929179Sandreas.hansson@arm.com     */
939179Sandreas.hansson@arm.com    MSHRQueue(const std::string &_label, int num_entries, int reserve,
949179Sandreas.hansson@arm.com              int index);
959179Sandreas.hansson@arm.com
969179Sandreas.hansson@arm.com    /** Destructor */
979179Sandreas.hansson@arm.com    ~MSHRQueue();
989179Sandreas.hansson@arm.com
999179Sandreas.hansson@arm.com    /**
1009179Sandreas.hansson@arm.com     * Find the first MSHR that matches the provided address.
1019180Sandreas.hansson@arm.com     * @param addr The address to find.
1029179Sandreas.hansson@arm.com     * @return Pointer to the matching MSHR, null if not found.
1039179Sandreas.hansson@arm.com     */
1049179Sandreas.hansson@arm.com    MSHR *findMatch(Addr addr) const;
1059179Sandreas.hansson@arm.com
1069157Sandreas.hansson@arm.com    /**
1079157Sandreas.hansson@arm.com     * Find and return all the matching entries in the provided vector.
1089157Sandreas.hansson@arm.com     * @param addr The address to find.
1099545Sandreas.hansson@arm.com     * @param matches The vector to return pointers to the matching entries.
1109545Sandreas.hansson@arm.com     * @return True if any matches are found, false otherwise.
1119157Sandreas.hansson@arm.com     * @todo Typedef the vector??
1129157Sandreas.hansson@arm.com     */
1139157Sandreas.hansson@arm.com    bool findMatches(Addr addr, std::vector<MSHR*>& matches) const;
1149157Sandreas.hansson@arm.com
1159179Sandreas.hansson@arm.com    /**
1169179Sandreas.hansson@arm.com     * Find any pending requests that overlap the given request.
1179418Sandreas.hansson@arm.com     * @param pkt The request to find.
1189418Sandreas.hansson@arm.com     * @return A pointer to the earliest matching MSHR.
1199418Sandreas.hansson@arm.com     */
1209418Sandreas.hansson@arm.com    MSHR *findPending(Addr addr, int size) const;
1219418Sandreas.hansson@arm.com
1229157Sandreas.hansson@arm.com    bool checkFunctional(PacketPtr pkt, Addr blk_addr);
1239157Sandreas.hansson@arm.com
1249157Sandreas.hansson@arm.com    /**
1259157Sandreas.hansson@arm.com     * Allocates a new MSHR for the request and size. This places the request
1269157Sandreas.hansson@arm.com     * as the first target in the MSHR.
1279157Sandreas.hansson@arm.com     * @param pkt The request to handle.
1289296Snilay@cs.wisc.edu     * @param size The number in bytes to fetch from memory.
1299296Snilay@cs.wisc.edu     * @return The a pointer to the MSHR allocated.
1309296Snilay@cs.wisc.edu     *
1319296Snilay@cs.wisc.edu     * @pre There are free entries.
1329296Snilay@cs.wisc.edu     */
1339296Snilay@cs.wisc.edu    MSHR *allocate(Addr addr, int size, PacketPtr &pkt,
1349296Snilay@cs.wisc.edu                   Tick when, Counter order);
1359296Snilay@cs.wisc.edu
1369296Snilay@cs.wisc.edu    /**
1379296Snilay@cs.wisc.edu     * Removes the given MSHR from the queue. This places the MSHR on the
1389296Snilay@cs.wisc.edu     * free list.
1399296Snilay@cs.wisc.edu     * @param mshr
1409157Sandreas.hansson@arm.com     */
1419157Sandreas.hansson@arm.com    void deallocate(MSHR *mshr);
1429157Sandreas.hansson@arm.com
1439179Sandreas.hansson@arm.com    /**
1449179Sandreas.hansson@arm.com     * Remove a MSHR from the queue. Returns an iterator into the
1459179Sandreas.hansson@arm.com     * allocatedList for faster squash implementation.
1469179Sandreas.hansson@arm.com     * @param mshr The MSHR to remove.
1479179Sandreas.hansson@arm.com     * @return An iterator to the next entry in the allocatedList.
1489179Sandreas.hansson@arm.com     */
1499179Sandreas.hansson@arm.com    MSHR::Iterator deallocateOne(MSHR *mshr);
1509179Sandreas.hansson@arm.com
1519180Sandreas.hansson@arm.com    /**
1529179Sandreas.hansson@arm.com     * Moves the MSHR to the front of the pending list if it is not
1539179Sandreas.hansson@arm.com     * in service.
1549179Sandreas.hansson@arm.com     * @param mshr The entry to move.
1559179Sandreas.hansson@arm.com     */
1569179Sandreas.hansson@arm.com    void moveToFront(MSHR *mshr);
1579180Sandreas.hansson@arm.com
1589179Sandreas.hansson@arm.com    /**
1599179Sandreas.hansson@arm.com     * Mark the given MSHR as in service. This removes the MSHR from the
1609179Sandreas.hansson@arm.com     * readyList. Deallocates the MSHR if it does not expect a response.
1619179Sandreas.hansson@arm.com     * @param mshr The MSHR to mark in service.
1629179Sandreas.hansson@arm.com     */
1639179Sandreas.hansson@arm.com    void markInService(MSHR *mshr, PacketPtr pkt);
1649180Sandreas.hansson@arm.com
1659179Sandreas.hansson@arm.com    /**
1669180Sandreas.hansson@arm.com     * Mark an in service entry as pending, used to resend a request.
1679179Sandreas.hansson@arm.com     * @param mshr The MSHR to resend.
1689179Sandreas.hansson@arm.com     */
1699179Sandreas.hansson@arm.com    void markPending(MSHR *mshr);
1709179Sandreas.hansson@arm.com
1719179Sandreas.hansson@arm.com    /**
1729179Sandreas.hansson@arm.com     * Squash outstanding requests with the given thread number. If a request
1739179Sandreas.hansson@arm.com     * is in service, just squashes the targets.
1749179Sandreas.hansson@arm.com     * @param threadNum The thread to squash.
1759157Sandreas.hansson@arm.com     */
1769179Sandreas.hansson@arm.com    void squash(int threadNum);
1779157Sandreas.hansson@arm.com
1789157Sandreas.hansson@arm.com    /**
1799157Sandreas.hansson@arm.com     * Returns true if the pending list is not empty.
1809157Sandreas.hansson@arm.com     * @return True if there are outstanding requests.
1819179Sandreas.hansson@arm.com     */
1829157Sandreas.hansson@arm.com    bool havePending() const
1839180Sandreas.hansson@arm.com    {
1849157Sandreas.hansson@arm.com        return !readyList.empty();
1859179Sandreas.hansson@arm.com    }
1869157Sandreas.hansson@arm.com
1879180Sandreas.hansson@arm.com    /**
1889180Sandreas.hansson@arm.com     * Returns true if there are no free entries.
1899157Sandreas.hansson@arm.com     * @return True if this queue is full.
1909157Sandreas.hansson@arm.com     */
1919157Sandreas.hansson@arm.com    bool isFull() const
1929157Sandreas.hansson@arm.com    {
193        return (allocated > numEntries - numReserve);
194    }
195
196    /**
197     * Returns the MSHR at the head of the readyList.
198     * @return The next request to service.
199     */
200    MSHR *getNextMSHR() const
201    {
202        if (readyList.empty() || readyList.front()->readyTime > curTick) {
203            return NULL;
204        }
205        return readyList.front();
206    }
207
208    Tick nextMSHRReadyTime() const
209    {
210        return readyList.empty() ? MaxTick : readyList.front()->readyTime;
211    }
212};
213
214#endif //__MEM__CACHE__MISS__MSHR_QUEUE_HH__
215