mshr_queue.cc revision 10764
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 * Definition of MSHRQueue class functions. 4611051Sandreas.hansson@arm.com */ 472810Srdreslin@umich.edu 482810Srdreslin@umich.edu#include "base/trace.hh" 492810Srdreslin@umich.edu#include "mem/cache/mshr_queue.hh" 502810Srdreslin@umich.edu#include "debug/Drain.hh" 5111051Sandreas.hansson@arm.com 522810Srdreslin@umich.eduusing namespace std; 532810Srdreslin@umich.edu 5411051Sandreas.hansson@arm.comMSHRQueue::MSHRQueue(const std::string &_label, 552810Srdreslin@umich.edu int num_entries, int reserve, int demand_reserve, 5611051Sandreas.hansson@arm.com int _index) 5711051Sandreas.hansson@arm.com : label(_label), numEntries(num_entries + reserve - 1), 5811051Sandreas.hansson@arm.com numReserve(reserve), demandReserve(demand_reserve), 5911051Sandreas.hansson@arm.com registers(numEntries), drainManager(NULL), allocated(0), 6011051Sandreas.hansson@arm.com inServiceEntries(0), index(_index) 6111051Sandreas.hansson@arm.com{ 6211051Sandreas.hansson@arm.com for (int i = 0; i < numEntries; ++i) { 6311051Sandreas.hansson@arm.com registers[i].queue = this; 6411051Sandreas.hansson@arm.com freeList.push_back(®isters[i]); 6511051Sandreas.hansson@arm.com } 6611053Sandreas.hansson@arm.com} 6711053Sandreas.hansson@arm.com 6811051Sandreas.hansson@arm.comMSHR * 6911051Sandreas.hansson@arm.comMSHRQueue::findMatch(Addr blk_addr, bool is_secure) const 7011051Sandreas.hansson@arm.com{ 7111197Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 7211197Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 7311199Sandreas.hansson@arm.com for (; i != end; ++i) { 7411197Sandreas.hansson@arm.com MSHR *mshr = *i; 7511197Sandreas.hansson@arm.com if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) { 7611197Sandreas.hansson@arm.com return mshr; 7711051Sandreas.hansson@arm.com } 7811051Sandreas.hansson@arm.com } 7911051Sandreas.hansson@arm.com return NULL; 8011051Sandreas.hansson@arm.com} 8111051Sandreas.hansson@arm.com 8211051Sandreas.hansson@arm.combool 8311051Sandreas.hansson@arm.comMSHRQueue::findMatches(Addr blk_addr, bool is_secure, 8411051Sandreas.hansson@arm.com vector<MSHR*>& matches) const 8511051Sandreas.hansson@arm.com{ 8611051Sandreas.hansson@arm.com // Need an empty vector 8711051Sandreas.hansson@arm.com assert(matches.empty()); 8811051Sandreas.hansson@arm.com bool retval = false; 8911051Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 9011051Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 9111051Sandreas.hansson@arm.com for (; i != end; ++i) { 9211051Sandreas.hansson@arm.com MSHR *mshr = *i; 9311051Sandreas.hansson@arm.com if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) { 9411051Sandreas.hansson@arm.com retval = true; 9511051Sandreas.hansson@arm.com matches.push_back(mshr); 9611051Sandreas.hansson@arm.com } 9711051Sandreas.hansson@arm.com } 9811051Sandreas.hansson@arm.com return retval; 9911051Sandreas.hansson@arm.com} 10011051Sandreas.hansson@arm.com 10111051Sandreas.hansson@arm.com 10211051Sandreas.hansson@arm.combool 10311051Sandreas.hansson@arm.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 10411051Sandreas.hansson@arm.com{ 10511051Sandreas.hansson@arm.com pkt->pushLabel(label); 10611051Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 10711051Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 10811051Sandreas.hansson@arm.com for (; i != end; ++i) { 10911051Sandreas.hansson@arm.com MSHR *mshr = *i; 11011051Sandreas.hansson@arm.com if (mshr->blkAddr == blk_addr && mshr->checkFunctional(pkt)) { 11111051Sandreas.hansson@arm.com pkt->popLabel(); 11211051Sandreas.hansson@arm.com return true; 11311051Sandreas.hansson@arm.com } 11411051Sandreas.hansson@arm.com } 11511051Sandreas.hansson@arm.com pkt->popLabel(); 11611051Sandreas.hansson@arm.com return false; 11711051Sandreas.hansson@arm.com} 11811051Sandreas.hansson@arm.com 11911051Sandreas.hansson@arm.com 12011051Sandreas.hansson@arm.comMSHR * 12111051Sandreas.hansson@arm.comMSHRQueue::findPending(Addr blk_addr, bool is_secure) const 12211051Sandreas.hansson@arm.com{ 12311051Sandreas.hansson@arm.com MSHR::ConstIterator i = readyList.begin(); 12411051Sandreas.hansson@arm.com MSHR::ConstIterator end = readyList.end(); 12511051Sandreas.hansson@arm.com for (; i != end; ++i) { 12611051Sandreas.hansson@arm.com MSHR *mshr = *i; 12711051Sandreas.hansson@arm.com if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) { 12811051Sandreas.hansson@arm.com return mshr; 12911051Sandreas.hansson@arm.com } 13011051Sandreas.hansson@arm.com } 13111051Sandreas.hansson@arm.com return NULL; 13211051Sandreas.hansson@arm.com} 13311051Sandreas.hansson@arm.com 13411051Sandreas.hansson@arm.com 13511051Sandreas.hansson@arm.comMSHR::Iterator 13611051Sandreas.hansson@arm.comMSHRQueue::addToReadyList(MSHR *mshr) 13711051Sandreas.hansson@arm.com{ 13811051Sandreas.hansson@arm.com if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 13911051Sandreas.hansson@arm.com return readyList.insert(readyList.end(), mshr); 14011051Sandreas.hansson@arm.com } 14111051Sandreas.hansson@arm.com 14211051Sandreas.hansson@arm.com MSHR::Iterator i = readyList.begin(); 14311051Sandreas.hansson@arm.com MSHR::Iterator end = readyList.end(); 14411051Sandreas.hansson@arm.com for (; i != end; ++i) { 14511051Sandreas.hansson@arm.com if ((*i)->readyTime > mshr->readyTime) { 14611051Sandreas.hansson@arm.com return readyList.insert(i, mshr); 14711051Sandreas.hansson@arm.com } 14811051Sandreas.hansson@arm.com } 14911051Sandreas.hansson@arm.com assert(false); 15011051Sandreas.hansson@arm.com return end; // keep stupid compilers happy 15111051Sandreas.hansson@arm.com} 15211051Sandreas.hansson@arm.com 15311051Sandreas.hansson@arm.com 15411051Sandreas.hansson@arm.comMSHR * 15511051Sandreas.hansson@arm.comMSHRQueue::allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt, 15611051Sandreas.hansson@arm.com Tick when_ready, Counter order) 15711051Sandreas.hansson@arm.com{ 15811051Sandreas.hansson@arm.com assert(!freeList.empty()); 15911051Sandreas.hansson@arm.com MSHR *mshr = freeList.front(); 16011284Sandreas.hansson@arm.com assert(mshr->getNumTargets() == 0); 16111051Sandreas.hansson@arm.com freeList.pop_front(); 16211051Sandreas.hansson@arm.com 16311051Sandreas.hansson@arm.com mshr->allocate(blk_addr, blk_size, pkt, when_ready, order); 16411051Sandreas.hansson@arm.com mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 16511051Sandreas.hansson@arm.com mshr->readyIter = addToReadyList(mshr); 16611051Sandreas.hansson@arm.com 16711051Sandreas.hansson@arm.com allocated += 1; 16811284Sandreas.hansson@arm.com return mshr; 16911284Sandreas.hansson@arm.com} 17011284Sandreas.hansson@arm.com 17111284Sandreas.hansson@arm.com 17211051Sandreas.hansson@arm.comvoid 17311284Sandreas.hansson@arm.comMSHRQueue::deallocate(MSHR *mshr) 17411051Sandreas.hansson@arm.com{ 17511051Sandreas.hansson@arm.com deallocateOne(mshr); 17611051Sandreas.hansson@arm.com} 17711284Sandreas.hansson@arm.com 17811284Sandreas.hansson@arm.comMSHR::Iterator 17911284Sandreas.hansson@arm.comMSHRQueue::deallocateOne(MSHR *mshr) 18011284Sandreas.hansson@arm.com{ 18111051Sandreas.hansson@arm.com MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 18211051Sandreas.hansson@arm.com freeList.push_front(mshr); 18311051Sandreas.hansson@arm.com allocated--; 18411051Sandreas.hansson@arm.com if (mshr->inService) { 18511051Sandreas.hansson@arm.com inServiceEntries--; 18611051Sandreas.hansson@arm.com } else { 18711051Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 18811051Sandreas.hansson@arm.com } 18911051Sandreas.hansson@arm.com mshr->deallocate(); 19011051Sandreas.hansson@arm.com if (drainManager && allocated == 0) { 19111051Sandreas.hansson@arm.com // Notify the drain manager that we have completed draining if 19211051Sandreas.hansson@arm.com // there are no other outstanding requests in this MSHR queue. 19311051Sandreas.hansson@arm.com DPRINTF(Drain, "MSHRQueue now empty, signalling drained\n"); 19411051Sandreas.hansson@arm.com drainManager->signalDrainDone(); 19511051Sandreas.hansson@arm.com drainManager = NULL; 19611051Sandreas.hansson@arm.com setDrainState(Drainable::Drained); 19711051Sandreas.hansson@arm.com } 19811051Sandreas.hansson@arm.com return retval; 19911051Sandreas.hansson@arm.com} 20011284Sandreas.hansson@arm.com 20111051Sandreas.hansson@arm.comvoid 20211051Sandreas.hansson@arm.comMSHRQueue::moveToFront(MSHR *mshr) 20311051Sandreas.hansson@arm.com{ 20411051Sandreas.hansson@arm.com if (!mshr->inService) { 20511051Sandreas.hansson@arm.com assert(mshr == *(mshr->readyIter)); 20611284Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 20711051Sandreas.hansson@arm.com mshr->readyIter = readyList.insert(readyList.begin(), mshr); 20811284Sandreas.hansson@arm.com } 20911051Sandreas.hansson@arm.com} 21011197Sandreas.hansson@arm.com 21111197Sandreas.hansson@arm.comvoid 21211197Sandreas.hansson@arm.comMSHRQueue::markInService(MSHR *mshr, bool pending_dirty_resp) 21311197Sandreas.hansson@arm.com{ 21411051Sandreas.hansson@arm.com if (mshr->markInService(pending_dirty_resp)) { 21511284Sandreas.hansson@arm.com deallocate(mshr); 21611051Sandreas.hansson@arm.com } else { 21711284Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 21811284Sandreas.hansson@arm.com inServiceEntries += 1; 21911284Sandreas.hansson@arm.com } 22011051Sandreas.hansson@arm.com} 22111051Sandreas.hansson@arm.com 22211051Sandreas.hansson@arm.comvoid 22311284Sandreas.hansson@arm.comMSHRQueue::markPending(MSHR *mshr) 22411284Sandreas.hansson@arm.com{ 22511284Sandreas.hansson@arm.com assert(mshr->inService); 22611284Sandreas.hansson@arm.com mshr->inService = false; 22711051Sandreas.hansson@arm.com --inServiceEntries; 22811051Sandreas.hansson@arm.com /** 22911051Sandreas.hansson@arm.com * @ todo might want to add rerequests to front of pending list for 23011284Sandreas.hansson@arm.com * performance. 23111284Sandreas.hansson@arm.com */ 23211284Sandreas.hansson@arm.com mshr->readyIter = addToReadyList(mshr); 23311197Sandreas.hansson@arm.com} 23411284Sandreas.hansson@arm.com 23511284Sandreas.hansson@arm.combool 23611284Sandreas.hansson@arm.comMSHRQueue::forceDeallocateTarget(MSHR *mshr) 23711284Sandreas.hansson@arm.com{ 23811284Sandreas.hansson@arm.com bool was_full = isFull(); 23911284Sandreas.hansson@arm.com assert(mshr->hasTargets()); 24011284Sandreas.hansson@arm.com // Pop the prefetch off of the target list 24111284Sandreas.hansson@arm.com mshr->popTarget(); 24211284Sandreas.hansson@arm.com // Delete mshr if no remaining targets 24311284Sandreas.hansson@arm.com if (!mshr->hasTargets() && !mshr->promoteDeferredTargets()) { 24411284Sandreas.hansson@arm.com deallocateOne(mshr); 24511284Sandreas.hansson@arm.com } 24611284Sandreas.hansson@arm.com 24711284Sandreas.hansson@arm.com // Notify if MSHR queue no longer full 24811284Sandreas.hansson@arm.com return was_full && !isFull(); 24911197Sandreas.hansson@arm.com} 25011284Sandreas.hansson@arm.com 25111284Sandreas.hansson@arm.comvoid 25211284Sandreas.hansson@arm.comMSHRQueue::squash(int threadNum) 25311284Sandreas.hansson@arm.com{ 25411284Sandreas.hansson@arm.com MSHR::Iterator i = allocatedList.begin(); 25511284Sandreas.hansson@arm.com MSHR::Iterator end = allocatedList.end(); 25611284Sandreas.hansson@arm.com for (; i != end;) { 25711197Sandreas.hansson@arm.com MSHR *mshr = *i; 25811051Sandreas.hansson@arm.com if (mshr->threadNum == threadNum) { 25911051Sandreas.hansson@arm.com while (mshr->hasTargets()) { 26011051Sandreas.hansson@arm.com mshr->popTarget(); 26111051Sandreas.hansson@arm.com assert(0/*target->req->threadId()*/ == threadNum); 26211051Sandreas.hansson@arm.com } 26311284Sandreas.hansson@arm.com assert(!mshr->hasTargets()); 26411284Sandreas.hansson@arm.com assert(mshr->getNumTargets()==0); 26511051Sandreas.hansson@arm.com if (!mshr->inService) { 26611051Sandreas.hansson@arm.com i = deallocateOne(mshr); 26711051Sandreas.hansson@arm.com } else { 26811051Sandreas.hansson@arm.com //mshr->pkt->flags &= ~CACHE_LINE_FILL; 26911284Sandreas.hansson@arm.com ++i; 27011051Sandreas.hansson@arm.com } 27111051Sandreas.hansson@arm.com } else { 27211051Sandreas.hansson@arm.com ++i; 27311284Sandreas.hansson@arm.com } 27411051Sandreas.hansson@arm.com } 27511197Sandreas.hansson@arm.com} 27611197Sandreas.hansson@arm.com 27711197Sandreas.hansson@arm.comunsigned int 27811197Sandreas.hansson@arm.comMSHRQueue::drain(DrainManager *dm) 27911051Sandreas.hansson@arm.com{ 28011051Sandreas.hansson@arm.com if (allocated == 0) { 28111051Sandreas.hansson@arm.com setDrainState(Drainable::Drained); 28211051Sandreas.hansson@arm.com return 0; 28311051Sandreas.hansson@arm.com } else { 28411051Sandreas.hansson@arm.com drainManager = dm; 28511051Sandreas.hansson@arm.com setDrainState(Drainable::Draining); 28611051Sandreas.hansson@arm.com return 1; 28711051Sandreas.hansson@arm.com } 28811051Sandreas.hansson@arm.com} 28911051Sandreas.hansson@arm.com