mshr_queue.hh revision 7667
12810SN/A/* 22810SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32810SN/A * All rights reserved. 42810SN/A * 52810SN/A * Redistribution and use in source and binary forms, with or without 62810SN/A * modification, are permitted provided that the following conditions are 72810SN/A * met: redistributions of source code must retain the above copyright 82810SN/A * notice, this list of conditions and the following disclaimer; 92810SN/A * redistributions in binary form must reproduce the above copyright 102810SN/A * notice, this list of conditions and the following disclaimer in the 112810SN/A * documentation and/or other materials provided with the distribution; 122810SN/A * neither the name of the copyright holders nor the names of its 132810SN/A * contributors may be used to endorse or promote products derived from 142810SN/A * this software without specific prior written permission. 152810SN/A * 162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810SN/A * 282810SN/A * Authors: Erik Hallnor 292810SN/A */ 302810SN/A 312810SN/A/** @file 322810SN/A * Declaration of a structure to manage MSHRs. 332810SN/A */ 342810SN/A 354626SN/A#ifndef __MEM__CACHE__MISS__MSHR_QUEUE_HH__ 364626SN/A#define __MEM__CACHE__MISS__MSHR_QUEUE_HH__ 372810SN/A 382810SN/A#include <vector> 394626SN/A 404626SN/A#include "mem/packet.hh" 415338Sstever@gmail.com#include "mem/cache/mshr.hh" 422810SN/A 432810SN/A/** 443374SN/A * A Class for maintaining a list of pending and allocated memory requests. 452810SN/A */ 464626SN/Aclass MSHRQueue 474626SN/A{ 482810SN/A private: 495314SN/A /** Local label (for functional print requests) */ 505314SN/A const std::string label; 515314SN/A 522810SN/A /** MSHR storage. */ 534626SN/A MSHR *registers; 544626SN/A /** Holds pointers to all allocated entries. */ 552810SN/A MSHR::List allocatedList; 564626SN/A /** Holds pointers to entries that haven't been sent to the bus. */ 574666SN/A MSHR::List readyList; 584626SN/A /** Holds non allocated entries. */ 592810SN/A MSHR::List freeList; 602810SN/A 612810SN/A // Parameters 622810SN/A /** 634626SN/A * The total number of entries in this queue. This number is set as the 644626SN/A * number of entries requested plus (numReserve - 1). This allows for 654626SN/A * the same number of effective entries while still maintaining the reserve. 662810SN/A */ 674626SN/A const int numEntries; 682810SN/A 692810SN/A /** 704626SN/A * The number of entries to hold in reserve. This is needed because copy 714626SN/A * operations can allocate upto 4 entries at one time. 722810SN/A */ 732810SN/A const int numReserve; 742810SN/A 754666SN/A MSHR::Iterator addToReadyList(MSHR *mshr); 764666SN/A 774666SN/A 782810SN/A public: 794626SN/A /** The number of allocated entries. */ 802810SN/A int allocated; 814626SN/A /** The number of entries that have been forwarded to the bus. */ 824626SN/A int inServiceEntries; 834628SN/A /** The index of this queue within the cache (MSHR queue vs. write 844628SN/A * buffer). */ 854628SN/A const int index; 862810SN/A 872810SN/A /** 884626SN/A * Create a queue with a given number of entries. 894626SN/A * @param num_entrys The number of entries in this queue. 904626SN/A * @param reserve The minimum number of entries needed to satisfy 914626SN/A * any access. 922810SN/A */ 935314SN/A MSHRQueue(const std::string &_label, int num_entries, int reserve, 945314SN/A int index); 952810SN/A 962810SN/A /** Destructor */ 972810SN/A ~MSHRQueue(); 982810SN/A 992810SN/A /** 1004626SN/A * Find the first MSHR that matches the provided address. 1012810SN/A * @param addr The address to find. 1022810SN/A * @return Pointer to the matching MSHR, null if not found. 1032810SN/A */ 1044626SN/A MSHR *findMatch(Addr addr) const; 1052810SN/A 1062810SN/A /** 1074626SN/A * Find and return all the matching entries in the provided vector. 1082810SN/A * @param addr The address to find. 1094626SN/A * @param matches The vector to return pointers to the matching entries. 1102810SN/A * @return True if any matches are found, false otherwise. 1112810SN/A * @todo Typedef the vector?? 1122810SN/A */ 1132991SN/A bool findMatches(Addr addr, std::vector<MSHR*>& matches) const; 1142810SN/A 1152810SN/A /** 1163374SN/A * Find any pending requests that overlap the given request. 1172982SN/A * @param pkt The request to find. 1182810SN/A * @return A pointer to the earliest matching MSHR. 1192810SN/A */ 1204626SN/A MSHR *findPending(Addr addr, int size) const; 1212810SN/A 1224920SN/A bool checkFunctional(PacketPtr pkt, Addr blk_addr); 1234920SN/A 1242810SN/A /** 1253374SN/A * Allocates a new MSHR for the request and size. This places the request 1262810SN/A * as the first target in the MSHR. 1272982SN/A * @param pkt The request to handle. 1282810SN/A * @param size The number in bytes to fetch from memory. 1292810SN/A * @return The a pointer to the MSHR allocated. 1302810SN/A * 1314626SN/A * @pre There are free entries. 1322810SN/A */ 1334666SN/A MSHR *allocate(Addr addr, int size, PacketPtr &pkt, 1344666SN/A Tick when, Counter order); 1352810SN/A 1362810SN/A /** 1372810SN/A * Removes the given MSHR from the queue. This places the MSHR on the 1382810SN/A * free list. 1392810SN/A * @param mshr 1402810SN/A */ 1414626SN/A void deallocate(MSHR *mshr); 1422810SN/A 1432810SN/A /** 1444626SN/A * Remove a MSHR from the queue. Returns an iterator into the 1454626SN/A * allocatedList for faster squash implementation. 1462810SN/A * @param mshr The MSHR to remove. 1472810SN/A * @return An iterator to the next entry in the allocatedList. 1482810SN/A */ 1494626SN/A MSHR::Iterator deallocateOne(MSHR *mshr); 1502810SN/A 1512810SN/A /** 1524626SN/A * Moves the MSHR to the front of the pending list if it is not 1534626SN/A * in service. 1544626SN/A * @param mshr The entry to move. 1552810SN/A */ 1562810SN/A void moveToFront(MSHR *mshr); 1572810SN/A 1582810SN/A /** 1592810SN/A * Mark the given MSHR as in service. This removes the MSHR from the 1604666SN/A * readyList. Deallocates the MSHR if it does not expect a response. 1612810SN/A * @param mshr The MSHR to mark in service. 1622810SN/A */ 1637667Ssteve.reinhardt@amd.com void markInService(MSHR *mshr, PacketPtr pkt); 1642810SN/A 1652810SN/A /** 1664626SN/A * Mark an in service entry as pending, used to resend a request. 1672810SN/A * @param mshr The MSHR to resend. 1682810SN/A */ 1694626SN/A void markPending(MSHR *mshr); 1702810SN/A 1712810SN/A /** 1723374SN/A * Squash outstanding requests with the given thread number. If a request 1732810SN/A * is in service, just squashes the targets. 1742982SN/A * @param threadNum The thread to squash. 1752810SN/A */ 1762812SN/A void squash(int threadNum); 1772810SN/A 1782810SN/A /** 1792810SN/A * Returns true if the pending list is not empty. 1803374SN/A * @return True if there are outstanding requests. 1812810SN/A */ 1822810SN/A bool havePending() const 1832810SN/A { 1844666SN/A return !readyList.empty(); 1852810SN/A } 1862810SN/A 1872810SN/A /** 1884626SN/A * Returns true if there are no free entries. 1892810SN/A * @return True if this queue is full. 1902810SN/A */ 1912810SN/A bool isFull() const 1922810SN/A { 1934626SN/A return (allocated > numEntries - numReserve); 1942810SN/A } 1952810SN/A 1962810SN/A /** 1974666SN/A * Returns the MSHR at the head of the readyList. 1983374SN/A * @return The next request to service. 1992810SN/A */ 2004626SN/A MSHR *getNextMSHR() const 2012810SN/A { 2024871SN/A if (readyList.empty() || readyList.front()->readyTime > curTick) { 2032810SN/A return NULL; 2042810SN/A } 2054666SN/A return readyList.front(); 2064666SN/A } 2074666SN/A 2084871SN/A Tick nextMSHRReadyTime() const 2094666SN/A { 2104871SN/A return readyList.empty() ? MaxTick : readyList.front()->readyTime; 2112810SN/A } 2122810SN/A}; 2132810SN/A 2144626SN/A#endif //__MEM__CACHE__MISS__MSHR_QUEUE_HH__ 215