mshr_queue.cc revision 10679
17396Sgblack@eecs.umich.edu/* 27396Sgblack@eecs.umich.edu * Copyright (c) 2012-2013 ARM Limited 37396Sgblack@eecs.umich.edu * All rights reserved. 47396Sgblack@eecs.umich.edu * 57396Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67396Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77396Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87396Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97396Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107396Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117396Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127396Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137396Sgblack@eecs.umich.edu * 147396Sgblack@eecs.umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 157396Sgblack@eecs.umich.edu * All rights reserved. 167396Sgblack@eecs.umich.edu * 177396Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 187396Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 197396Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 207396Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 217396Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 227396Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 237396Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 247396Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 257396Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 267396Sgblack@eecs.umich.edu * this software without specific prior written permission. 277396Sgblack@eecs.umich.edu * 287396Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297396Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307396Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317396Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327396Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337396Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347396Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357396Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367396Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377396Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387396Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397396Sgblack@eecs.umich.edu * 407396Sgblack@eecs.umich.edu * Authors: Erik Hallnor 417396Sgblack@eecs.umich.edu * Andreas Sandberg 427434Sgblack@eecs.umich.edu */ 437434Sgblack@eecs.umich.edu 447434Sgblack@eecs.umich.edu/** @file 457434Sgblack@eecs.umich.edu * Definition of MSHRQueue class functions. 467434Sgblack@eecs.umich.edu */ 477434Sgblack@eecs.umich.edu 487396Sgblack@eecs.umich.edu#include "base/trace.hh" 497396Sgblack@eecs.umich.edu#include "mem/cache/mshr_queue.hh" 507396Sgblack@eecs.umich.edu#include "debug/Drain.hh" 517396Sgblack@eecs.umich.edu 527396Sgblack@eecs.umich.eduusing namespace std; 537396Sgblack@eecs.umich.edu 547396Sgblack@eecs.umich.eduMSHRQueue::MSHRQueue(const std::string &_label, 557396Sgblack@eecs.umich.edu int num_entries, int reserve, int demand_reserve, 567396Sgblack@eecs.umich.edu int _index) 577396Sgblack@eecs.umich.edu : label(_label), numEntries(num_entries + reserve - 1), 587396Sgblack@eecs.umich.edu numReserve(reserve), demandReserve(demand_reserve), 597396Sgblack@eecs.umich.edu registers(numEntries), drainManager(NULL), allocated(0), 607396Sgblack@eecs.umich.edu inServiceEntries(0), index(_index) 617396Sgblack@eecs.umich.edu{ 627396Sgblack@eecs.umich.edu for (int i = 0; i < numEntries; ++i) { 637396Sgblack@eecs.umich.edu registers[i].queue = this; 647396Sgblack@eecs.umich.edu freeList.push_back(®isters[i]); 657396Sgblack@eecs.umich.edu } 667396Sgblack@eecs.umich.edu} 677396Sgblack@eecs.umich.edu 687396Sgblack@eecs.umich.eduMSHR * 697396Sgblack@eecs.umich.eduMSHRQueue::findMatch(Addr addr, bool is_secure) const 707396Sgblack@eecs.umich.edu{ 717396Sgblack@eecs.umich.edu MSHR::ConstIterator i = allocatedList.begin(); 727396Sgblack@eecs.umich.edu MSHR::ConstIterator end = allocatedList.end(); 737396Sgblack@eecs.umich.edu for (; i != end; ++i) { 747396Sgblack@eecs.umich.edu MSHR *mshr = *i; 757396Sgblack@eecs.umich.edu if (mshr->addr == addr && mshr->isSecure == is_secure) { 767396Sgblack@eecs.umich.edu return mshr; 777396Sgblack@eecs.umich.edu } 787396Sgblack@eecs.umich.edu } 797396Sgblack@eecs.umich.edu return NULL; 807396Sgblack@eecs.umich.edu} 817396Sgblack@eecs.umich.edu 827396Sgblack@eecs.umich.edubool 837396Sgblack@eecs.umich.eduMSHRQueue::findMatches(Addr addr, bool is_secure, vector<MSHR*>& matches) const 847396Sgblack@eecs.umich.edu{ 857396Sgblack@eecs.umich.edu // Need an empty vector 867396Sgblack@eecs.umich.edu assert(matches.empty()); 877396Sgblack@eecs.umich.edu bool retval = false; 887396Sgblack@eecs.umich.edu MSHR::ConstIterator i = allocatedList.begin(); 897396Sgblack@eecs.umich.edu MSHR::ConstIterator end = allocatedList.end(); 907396Sgblack@eecs.umich.edu for (; i != end; ++i) { 917396Sgblack@eecs.umich.edu MSHR *mshr = *i; 927396Sgblack@eecs.umich.edu if (mshr->addr == addr && mshr->isSecure == is_secure) { 937430Sgblack@eecs.umich.edu retval = true; 947639Sgblack@eecs.umich.edu matches.push_back(mshr); 957639Sgblack@eecs.umich.edu } 967639Sgblack@eecs.umich.edu } 977639Sgblack@eecs.umich.edu return retval; 987639Sgblack@eecs.umich.edu} 997639Sgblack@eecs.umich.edu 1007639Sgblack@eecs.umich.edu 1017639Sgblack@eecs.umich.edubool 1027639Sgblack@eecs.umich.eduMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 1037639Sgblack@eecs.umich.edu{ 1047639Sgblack@eecs.umich.edu pkt->pushLabel(label); 1057639Sgblack@eecs.umich.edu MSHR::ConstIterator i = allocatedList.begin(); 1067639Sgblack@eecs.umich.edu MSHR::ConstIterator end = allocatedList.end(); 1077639Sgblack@eecs.umich.edu for (; i != end; ++i) { 1087430Sgblack@eecs.umich.edu MSHR *mshr = *i; 1097430Sgblack@eecs.umich.edu if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) { 1107430Sgblack@eecs.umich.edu pkt->popLabel(); 1117430Sgblack@eecs.umich.edu return true; 1127430Sgblack@eecs.umich.edu } 1137430Sgblack@eecs.umich.edu } 1147430Sgblack@eecs.umich.edu pkt->popLabel(); 1157430Sgblack@eecs.umich.edu return false; 1167430Sgblack@eecs.umich.edu} 1177430Sgblack@eecs.umich.edu 1187430Sgblack@eecs.umich.edu 1197430Sgblack@eecs.umich.eduMSHR * 1207430Sgblack@eecs.umich.eduMSHRQueue::findPending(Addr addr, int size, bool is_secure) const 1217430Sgblack@eecs.umich.edu{ 1227430Sgblack@eecs.umich.edu MSHR::ConstIterator i = readyList.begin(); 1237430Sgblack@eecs.umich.edu MSHR::ConstIterator end = readyList.end(); 1247430Sgblack@eecs.umich.edu for (; i != end; ++i) { 1257430Sgblack@eecs.umich.edu MSHR *mshr = *i; 1267430Sgblack@eecs.umich.edu if (mshr->isSecure == is_secure) { 1277430Sgblack@eecs.umich.edu if (mshr->addr < addr) { 1287430Sgblack@eecs.umich.edu if (mshr->addr + mshr->size > addr) 1297430Sgblack@eecs.umich.edu return mshr; 1307430Sgblack@eecs.umich.edu } else { 1317430Sgblack@eecs.umich.edu if (addr + size > mshr->addr) 1327430Sgblack@eecs.umich.edu return mshr; 1337430Sgblack@eecs.umich.edu } 1347639Sgblack@eecs.umich.edu } 1357430Sgblack@eecs.umich.edu } 1367430Sgblack@eecs.umich.edu return NULL; 1377430Sgblack@eecs.umich.edu} 1387430Sgblack@eecs.umich.edu 1397430Sgblack@eecs.umich.edu 1407430Sgblack@eecs.umich.eduMSHR::Iterator 1417430Sgblack@eecs.umich.eduMSHRQueue::addToReadyList(MSHR *mshr) 1427430Sgblack@eecs.umich.edu{ 1437430Sgblack@eecs.umich.edu if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 1447430Sgblack@eecs.umich.edu return readyList.insert(readyList.end(), mshr); 1457430Sgblack@eecs.umich.edu } 1467430Sgblack@eecs.umich.edu 1477430Sgblack@eecs.umich.edu MSHR::Iterator i = readyList.begin(); 1487430Sgblack@eecs.umich.edu MSHR::Iterator end = readyList.end(); 1497430Sgblack@eecs.umich.edu for (; i != end; ++i) { 1507430Sgblack@eecs.umich.edu if ((*i)->readyTime > mshr->readyTime) { 1517639Sgblack@eecs.umich.edu return readyList.insert(i, mshr); 1527430Sgblack@eecs.umich.edu } 1537430Sgblack@eecs.umich.edu } 1547430Sgblack@eecs.umich.edu assert(false); 1557430Sgblack@eecs.umich.edu return end; // keep stupid compilers happy 1567430Sgblack@eecs.umich.edu} 1577430Sgblack@eecs.umich.edu 1587430Sgblack@eecs.umich.edu 1597639Sgblack@eecs.umich.eduMSHR * 1607430Sgblack@eecs.umich.eduMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 1617430Sgblack@eecs.umich.edu Tick when, Counter order) 1627430Sgblack@eecs.umich.edu{ 1637430Sgblack@eecs.umich.edu assert(!freeList.empty()); 1647430Sgblack@eecs.umich.edu MSHR *mshr = freeList.front(); 1657430Sgblack@eecs.umich.edu assert(mshr->getNumTargets() == 0); 1667430Sgblack@eecs.umich.edu freeList.pop_front(); 1677639Sgblack@eecs.umich.edu 1687430Sgblack@eecs.umich.edu mshr->allocate(addr, size, pkt, when, order); 1697430Sgblack@eecs.umich.edu mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 1707430Sgblack@eecs.umich.edu mshr->readyIter = addToReadyList(mshr); 1717430Sgblack@eecs.umich.edu 1727639Sgblack@eecs.umich.edu allocated += 1; 1737430Sgblack@eecs.umich.edu return mshr; 1747430Sgblack@eecs.umich.edu} 1757430Sgblack@eecs.umich.edu 1767430Sgblack@eecs.umich.edu 1777430Sgblack@eecs.umich.eduvoid 1787430Sgblack@eecs.umich.eduMSHRQueue::deallocate(MSHR *mshr) 1797430Sgblack@eecs.umich.edu{ 1807430Sgblack@eecs.umich.edu deallocateOne(mshr); 1817430Sgblack@eecs.umich.edu} 1827430Sgblack@eecs.umich.edu 1837639Sgblack@eecs.umich.eduMSHR::Iterator 1847430Sgblack@eecs.umich.eduMSHRQueue::deallocateOne(MSHR *mshr) 1857639Sgblack@eecs.umich.edu{ 1867430Sgblack@eecs.umich.edu MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 1877430Sgblack@eecs.umich.edu freeList.push_front(mshr); 1887430Sgblack@eecs.umich.edu allocated--; 1897639Sgblack@eecs.umich.edu if (mshr->inService) { 1907430Sgblack@eecs.umich.edu inServiceEntries--; 1917430Sgblack@eecs.umich.edu } else { 1927430Sgblack@eecs.umich.edu readyList.erase(mshr->readyIter); 1937430Sgblack@eecs.umich.edu } 1947430Sgblack@eecs.umich.edu mshr->deallocate(); 1957430Sgblack@eecs.umich.edu if (drainManager && allocated == 0) { 1967430Sgblack@eecs.umich.edu // Notify the drain manager that we have completed draining if 1977430Sgblack@eecs.umich.edu // there are no other outstanding requests in this MSHR queue. 1987430Sgblack@eecs.umich.edu DPRINTF(Drain, "MSHRQueue now empty, signalling drained\n"); 1997430Sgblack@eecs.umich.edu drainManager->signalDrainDone(); 2007639Sgblack@eecs.umich.edu drainManager = NULL; 2017430Sgblack@eecs.umich.edu setDrainState(Drainable::Drained); 2027430Sgblack@eecs.umich.edu } 2037430Sgblack@eecs.umich.edu return retval; 2047430Sgblack@eecs.umich.edu} 2057430Sgblack@eecs.umich.edu 2067430Sgblack@eecs.umich.eduvoid 2077430Sgblack@eecs.umich.eduMSHRQueue::moveToFront(MSHR *mshr) 2087430Sgblack@eecs.umich.edu{ 2097430Sgblack@eecs.umich.edu if (!mshr->inService) { 2107430Sgblack@eecs.umich.edu assert(mshr == *(mshr->readyIter)); 2117639Sgblack@eecs.umich.edu readyList.erase(mshr->readyIter); 2127430Sgblack@eecs.umich.edu mshr->readyIter = readyList.insert(readyList.begin(), mshr); 2137430Sgblack@eecs.umich.edu } 2147430Sgblack@eecs.umich.edu} 2157430Sgblack@eecs.umich.edu 2167430Sgblack@eecs.umich.eduvoid 2177430Sgblack@eecs.umich.eduMSHRQueue::markInService(MSHR *mshr, bool pending_dirty_resp) 2187430Sgblack@eecs.umich.edu{ 2197430Sgblack@eecs.umich.edu if (mshr->markInService(pending_dirty_resp)) { 2207430Sgblack@eecs.umich.edu deallocate(mshr); 2217430Sgblack@eecs.umich.edu } else { 2227639Sgblack@eecs.umich.edu readyList.erase(mshr->readyIter); 2237639Sgblack@eecs.umich.edu inServiceEntries += 1; 2247430Sgblack@eecs.umich.edu } 2257639Sgblack@eecs.umich.edu} 2267639Sgblack@eecs.umich.edu 2277430Sgblack@eecs.umich.eduvoid 2287430Sgblack@eecs.umich.eduMSHRQueue::markPending(MSHR *mshr) 2297430Sgblack@eecs.umich.edu{ 2307639Sgblack@eecs.umich.edu assert(mshr->inService); 2317430Sgblack@eecs.umich.edu mshr->inService = false; 2327639Sgblack@eecs.umich.edu --inServiceEntries; 2337430Sgblack@eecs.umich.edu /** 2347430Sgblack@eecs.umich.edu * @ todo might want to add rerequests to front of pending list for 2357430Sgblack@eecs.umich.edu * performance. 2367430Sgblack@eecs.umich.edu */ 2377430Sgblack@eecs.umich.edu mshr->readyIter = addToReadyList(mshr); 2387430Sgblack@eecs.umich.edu} 2397430Sgblack@eecs.umich.edu 2407430Sgblack@eecs.umich.edubool 2417430Sgblack@eecs.umich.eduMSHRQueue::forceDeallocateTarget(MSHR *mshr) 2427430Sgblack@eecs.umich.edu{ 2437430Sgblack@eecs.umich.edu bool was_full = isFull(); 2447430Sgblack@eecs.umich.edu assert(mshr->hasTargets()); 2457430Sgblack@eecs.umich.edu // Pop the prefetch off of the target list 2467430Sgblack@eecs.umich.edu mshr->popTarget(); 2477639Sgblack@eecs.umich.edu // Delete mshr if no remaining targets 2487430Sgblack@eecs.umich.edu if (!mshr->hasTargets() && !mshr->promoteDeferredTargets()) { 2497430Sgblack@eecs.umich.edu deallocateOne(mshr); 2507430Sgblack@eecs.umich.edu } 2517430Sgblack@eecs.umich.edu 2527430Sgblack@eecs.umich.edu // Notify if MSHR queue no longer full 2537430Sgblack@eecs.umich.edu return was_full && !isFull(); 2547430Sgblack@eecs.umich.edu} 2557430Sgblack@eecs.umich.edu 2567430Sgblack@eecs.umich.eduvoid 2577430Sgblack@eecs.umich.eduMSHRQueue::squash(int threadNum) 2587639Sgblack@eecs.umich.edu{ 2597639Sgblack@eecs.umich.edu MSHR::Iterator i = allocatedList.begin(); 2607430Sgblack@eecs.umich.edu MSHR::Iterator end = allocatedList.end(); 2617639Sgblack@eecs.umich.edu for (; i != end;) { 2627639Sgblack@eecs.umich.edu MSHR *mshr = *i; 2637430Sgblack@eecs.umich.edu if (mshr->threadNum == threadNum) { 2647430Sgblack@eecs.umich.edu while (mshr->hasTargets()) { 2657430Sgblack@eecs.umich.edu mshr->popTarget(); 2667430Sgblack@eecs.umich.edu assert(0/*target->req->threadId()*/ == threadNum); 2677430Sgblack@eecs.umich.edu } 2687430Sgblack@eecs.umich.edu assert(!mshr->hasTargets()); 2697430Sgblack@eecs.umich.edu assert(mshr->getNumTargets()==0); 2707430Sgblack@eecs.umich.edu if (!mshr->inService) { 2717430Sgblack@eecs.umich.edu i = deallocateOne(mshr); 2727430Sgblack@eecs.umich.edu } else { 2737430Sgblack@eecs.umich.edu //mshr->pkt->flags &= ~CACHE_LINE_FILL; 2747430Sgblack@eecs.umich.edu ++i; 2757430Sgblack@eecs.umich.edu } 2767639Sgblack@eecs.umich.edu } else { 2777430Sgblack@eecs.umich.edu ++i; 2787430Sgblack@eecs.umich.edu } 2797430Sgblack@eecs.umich.edu } 2807430Sgblack@eecs.umich.edu} 2817430Sgblack@eecs.umich.edu 2827430Sgblack@eecs.umich.eduunsigned int 2837430Sgblack@eecs.umich.eduMSHRQueue::drain(DrainManager *dm) 2847430Sgblack@eecs.umich.edu{ 2857430Sgblack@eecs.umich.edu if (allocated == 0) { 2867430Sgblack@eecs.umich.edu setDrainState(Drainable::Drained); 2877430Sgblack@eecs.umich.edu return 0; 2887430Sgblack@eecs.umich.edu } else { 2897430Sgblack@eecs.umich.edu drainManager = dm; 2907430Sgblack@eecs.umich.edu setDrainState(Drainable::Draining); 2917430Sgblack@eecs.umich.edu return 1; 2927430Sgblack@eecs.umich.edu } 2937430Sgblack@eecs.umich.edu} 2947430Sgblack@eecs.umich.edu