mshr_queue.hh revision 3374
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 __MSHR_QUEUE_HH__
369157Sandreas.hansson@arm.com#define __MSHR_QUEUE_HH__
379157Sandreas.hansson@arm.com
389157Sandreas.hansson@arm.com#include <vector>
399157Sandreas.hansson@arm.com#include "mem/cache/miss/mshr.hh"
409157Sandreas.hansson@arm.com
419157Sandreas.hansson@arm.com/**
429157Sandreas.hansson@arm.com * A Class for maintaining a list of pending and allocated memory requests.
439157Sandreas.hansson@arm.com */
449157Sandreas.hansson@arm.comclass MSHRQueue {
459157Sandreas.hansson@arm.com  private:
469157Sandreas.hansson@arm.com    /**  MSHR storage. */
479157Sandreas.hansson@arm.com    MSHR* registers;
489157Sandreas.hansson@arm.com    /** Holds pointers to all allocated MSHRs. */
499157Sandreas.hansson@arm.com    MSHR::List allocatedList;
509157Sandreas.hansson@arm.com    /** Holds pointers to MSHRs that haven't been sent to the bus. */
519157Sandreas.hansson@arm.com    MSHR::List pendingList;
529157Sandreas.hansson@arm.com    /** Holds non allocated MSHRs. */
539157Sandreas.hansson@arm.com    MSHR::List freeList;
549157Sandreas.hansson@arm.com
559157Sandreas.hansson@arm.com    // Parameters
569157Sandreas.hansson@arm.com    /**
579157Sandreas.hansson@arm.com     * The total number of MSHRs in this queue. This number is set as the
589157Sandreas.hansson@arm.com     * number of MSHRs requested plus (numReserve - 1). This allows for
599157Sandreas.hansson@arm.com     * the same number of effective MSHRs while still maintaining the reserve.
609157Sandreas.hansson@arm.com     */
619179Sandreas.hansson@arm.com    const int numMSHRs;
629179Sandreas.hansson@arm.com
639179Sandreas.hansson@arm.com    /**
649179Sandreas.hansson@arm.com     * The number of MSHRs to hold in reserve. This is needed because copy
659179Sandreas.hansson@arm.com     * operations can allocate upto 4 MSHRs at one time.
669179Sandreas.hansson@arm.com     */
679180Sandreas.hansson@arm.com    const int numReserve;
689179Sandreas.hansson@arm.com
699157Sandreas.hansson@arm.com  public:
709157Sandreas.hansson@arm.com    /** The number of allocated MSHRs. */
719157Sandreas.hansson@arm.com    int allocated;
729157Sandreas.hansson@arm.com    /** The number of MSHRs that have been forwarded to the bus. */
739157Sandreas.hansson@arm.com    int inServiceMSHRs;
749157Sandreas.hansson@arm.com    /** The number of targets waiting for response. */
759157Sandreas.hansson@arm.com    int allocatedTargets;
769179Sandreas.hansson@arm.com
779179Sandreas.hansson@arm.com    /**
789179Sandreas.hansson@arm.com     * Create a queue with a given number of MSHRs.
799179Sandreas.hansson@arm.com     * @param num_mshrs The number of MSHRs in this queue.
809179Sandreas.hansson@arm.com     * @param reserve The minimum number of MSHRs needed to satisfy any access.
819179Sandreas.hansson@arm.com     */
829179Sandreas.hansson@arm.com    MSHRQueue(int num_mshrs, int reserve = 1);
839179Sandreas.hansson@arm.com
849179Sandreas.hansson@arm.com    /** Destructor */
859179Sandreas.hansson@arm.com    ~MSHRQueue();
869179Sandreas.hansson@arm.com
879179Sandreas.hansson@arm.com    /**
889179Sandreas.hansson@arm.com     * Find the first MSHR that matches the provide address and asid.
899179Sandreas.hansson@arm.com     * @param addr The address to find.
909179Sandreas.hansson@arm.com     * @param asid The address space id.
919179Sandreas.hansson@arm.com     * @return Pointer to the matching MSHR, null if not found.
929179Sandreas.hansson@arm.com     */
939179Sandreas.hansson@arm.com    MSHR* findMatch(Addr addr) const;
949179Sandreas.hansson@arm.com
959179Sandreas.hansson@arm.com    /**
969179Sandreas.hansson@arm.com     * Find and return all the matching MSHRs in the provided vector.
979179Sandreas.hansson@arm.com     * @param addr The address to find.
989179Sandreas.hansson@arm.com     * @param asid The address space ID.
999180Sandreas.hansson@arm.com     * @param matches The vector to return pointers to the matching MSHRs.
1009179Sandreas.hansson@arm.com     * @return True if any matches are found, false otherwise.
1019179Sandreas.hansson@arm.com     * @todo Typedef the vector??
1029179Sandreas.hansson@arm.com     */
1039179Sandreas.hansson@arm.com    bool findMatches(Addr addr, std::vector<MSHR*>& matches) const;
1049157Sandreas.hansson@arm.com
1059157Sandreas.hansson@arm.com    /**
1069157Sandreas.hansson@arm.com     * Find any pending requests that overlap the given request.
1079157Sandreas.hansson@arm.com     * @param pkt The request to find.
1089157Sandreas.hansson@arm.com     * @return A pointer to the earliest matching MSHR.
1099157Sandreas.hansson@arm.com     */
1109157Sandreas.hansson@arm.com    MSHR* findPending(PacketPtr &pkt) const;
1119157Sandreas.hansson@arm.com
1129157Sandreas.hansson@arm.com    /**
1139179Sandreas.hansson@arm.com     * Allocates a new MSHR for the request and size. This places the request
1149179Sandreas.hansson@arm.com     * as the first target in the MSHR.
1159157Sandreas.hansson@arm.com     * @param pkt The request to handle.
1169157Sandreas.hansson@arm.com     * @param size The number in bytes to fetch from memory.
1179157Sandreas.hansson@arm.com     * @return The a pointer to the MSHR allocated.
1189157Sandreas.hansson@arm.com     *
1199157Sandreas.hansson@arm.com     * @pre There are free MSHRs.
1209157Sandreas.hansson@arm.com     */
1219157Sandreas.hansson@arm.com    MSHR* allocate(PacketPtr &pkt, int size = 0);
1229296Snilay@cs.wisc.edu
1239296Snilay@cs.wisc.edu    /**
1249296Snilay@cs.wisc.edu     * Allocate a read request for the given address, and places the given
1259296Snilay@cs.wisc.edu     * target on the target list.
1269296Snilay@cs.wisc.edu     * @param addr The address to fetch.
1279296Snilay@cs.wisc.edu     * @param asid The address space for the fetch.
1289296Snilay@cs.wisc.edu     * @param size The number of bytes to request.
1299296Snilay@cs.wisc.edu     * @param target The first target for the request.
1309296Snilay@cs.wisc.edu     * @return Pointer to the new MSHR.
1319296Snilay@cs.wisc.edu     */
1329296Snilay@cs.wisc.edu    MSHR* allocateFetch(Addr addr, int size, PacketPtr &target);
1339296Snilay@cs.wisc.edu
1349157Sandreas.hansson@arm.com    /**
1359157Sandreas.hansson@arm.com     * Allocate a target list for the given address.
1369157Sandreas.hansson@arm.com     * @param addr The address to fetch.
1379179Sandreas.hansson@arm.com     * @param asid The address space for the fetch.
1389179Sandreas.hansson@arm.com     * @param size The number of bytes to request.
1399179Sandreas.hansson@arm.com     * @return Pointer to the new MSHR.
1409179Sandreas.hansson@arm.com     */
1419179Sandreas.hansson@arm.com    MSHR* allocateTargetList(Addr addr, int size);
1429179Sandreas.hansson@arm.com
1439179Sandreas.hansson@arm.com    /**
1449179Sandreas.hansson@arm.com     * Removes the given MSHR from the queue. This places the MSHR on the
1459180Sandreas.hansson@arm.com     * free list.
1469179Sandreas.hansson@arm.com     * @param mshr
1479179Sandreas.hansson@arm.com     */
1489179Sandreas.hansson@arm.com    void deallocate(MSHR* mshr);
1499179Sandreas.hansson@arm.com
1509179Sandreas.hansson@arm.com    /**
1519180Sandreas.hansson@arm.com     * Allocates a target to the given MSHR. Used to keep track of the number
1529179Sandreas.hansson@arm.com     * of outstanding targets.
1539179Sandreas.hansson@arm.com     * @param mshr The MSHR to allocate the target to.
1549179Sandreas.hansson@arm.com     * @param pkt The target request.
1559179Sandreas.hansson@arm.com     */
1569179Sandreas.hansson@arm.com    void allocateTarget(MSHR* mshr, PacketPtr &pkt)
1579179Sandreas.hansson@arm.com    {
1589180Sandreas.hansson@arm.com        mshr->allocateTarget(pkt);
1599179Sandreas.hansson@arm.com        allocatedTargets += 1;
1609180Sandreas.hansson@arm.com    }
1619179Sandreas.hansson@arm.com
1629179Sandreas.hansson@arm.com    /**
1639179Sandreas.hansson@arm.com     * Remove a MSHR from the queue. Returns an iterator into the allocatedList
1649179Sandreas.hansson@arm.com     * for faster squash implementation.
1659179Sandreas.hansson@arm.com     * @param mshr The MSHR to remove.
1669179Sandreas.hansson@arm.com     * @return An iterator to the next entry in the allocatedList.
1679179Sandreas.hansson@arm.com     */
1689179Sandreas.hansson@arm.com    MSHR::Iterator deallocateOne(MSHR* mshr);
1699157Sandreas.hansson@arm.com
1709179Sandreas.hansson@arm.com    /**
1719157Sandreas.hansson@arm.com     * Moves the MSHR to the front of the pending list if it is not in service.
1729157Sandreas.hansson@arm.com     * @param mshr The mshr to move.
1739157Sandreas.hansson@arm.com     */
1749157Sandreas.hansson@arm.com    void moveToFront(MSHR *mshr);
1759179Sandreas.hansson@arm.com
1769157Sandreas.hansson@arm.com    /**
1779180Sandreas.hansson@arm.com     * Mark the given MSHR as in service. This removes the MSHR from the
1789157Sandreas.hansson@arm.com     * pendingList. Deallocates the MSHR if it does not expect a response.
1799179Sandreas.hansson@arm.com     * @param mshr The MSHR to mark in service.
1809157Sandreas.hansson@arm.com     */
1819180Sandreas.hansson@arm.com    void markInService(MSHR* mshr);
1829180Sandreas.hansson@arm.com
1839157Sandreas.hansson@arm.com    /**
1849157Sandreas.hansson@arm.com     * Mark an in service mshr as pending, used to resend a request.
1859157Sandreas.hansson@arm.com     * @param mshr The MSHR to resend.
1869157Sandreas.hansson@arm.com     * @param cmd The command to resend.
187     */
188    void markPending(MSHR* mshr, Packet::Command cmd);
189
190    /**
191     * Squash outstanding requests with the given thread number. If a request
192     * is in service, just squashes the targets.
193     * @param threadNum The thread to squash.
194     */
195    void squash(int threadNum);
196
197    /**
198     * Returns true if the pending list is not empty.
199     * @return True if there are outstanding requests.
200     */
201    bool havePending() const
202    {
203        return !pendingList.empty();
204    }
205
206    /**
207     * Returns true if there are no free MSHRs.
208     * @return True if this queue is full.
209     */
210    bool isFull() const
211    {
212        return (allocated > numMSHRs - numReserve);
213    }
214
215    /**
216     * Returns the request at the head of the pendingList.
217     * @return The next request to service.
218     */
219    PacketPtr getReq() const
220    {
221        if (pendingList.empty()) {
222            return NULL;
223        }
224        MSHR* mshr = pendingList.front();
225        return mshr->pkt;
226    }
227
228    /**
229     * Returns the number of outstanding targets.
230     * @return the number of allocated targets.
231     */
232    int getAllocatedTargets() const
233    {
234        return allocatedTargets;
235    }
236
237};
238
239#endif //__MSHR_QUEUE_HH__
240