mshr_queue.cc revision 10028
15131Sgblack@eecs.umich.edu/* 25131Sgblack@eecs.umich.edu * Copyright (c) 2012-2013 ARM Limited 35131Sgblack@eecs.umich.edu * All rights reserved. 45131Sgblack@eecs.umich.edu * 55131Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 65131Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 75131Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 85131Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 95131Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 105131Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 115131Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 125131Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 135131Sgblack@eecs.umich.edu * 145131Sgblack@eecs.umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 155131Sgblack@eecs.umich.edu * All rights reserved. 165131Sgblack@eecs.umich.edu * 175131Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 185131Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 195131Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 205131Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 215131Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 225131Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 235131Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 245131Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 255131Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 265131Sgblack@eecs.umich.edu * this software without specific prior written permission. 275131Sgblack@eecs.umich.edu * 285131Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 295390Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 305131Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 315131Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 325131Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 338739Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 345638Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 355629Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 365131Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 375637Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 385637Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 395637Sgblack@eecs.umich.edu * 405629Sgblack@eecs.umich.edu * Authors: Erik Hallnor 415629Sgblack@eecs.umich.edu * Andreas Sandberg 428335Snate@binkert.org */ 435630Sgblack@eecs.umich.edu 445630Sgblack@eecs.umich.edu/** @file 455630Sgblack@eecs.umich.edu * Definition of MSHRQueue class functions. 468335Snate@binkert.org */ 475633Sgblack@eecs.umich.edu 485636Sgblack@eecs.umich.edu#include "mem/cache/mshr_queue.hh" 495636Sgblack@eecs.umich.edu 508335Snate@binkert.orgusing namespace std; 515636Sgblack@eecs.umich.edu 525818Sgblack@eecs.umich.eduMSHRQueue::MSHRQueue(const std::string &_label, 535818Sgblack@eecs.umich.edu int num_entries, int reserve, int _index) 548335Snate@binkert.org : label(_label), numEntries(num_entries + reserve - 1), 555818Sgblack@eecs.umich.edu numReserve(reserve), registers(numEntries), 565831Sgblack@eecs.umich.edu drainManager(NULL), allocated(0), inServiceEntries(0), index(_index) 575831Sgblack@eecs.umich.edu{ 588335Snate@binkert.org for (int i = 0; i < numEntries; ++i) { 595831Sgblack@eecs.umich.edu registers[i].queue = this; 605636Sgblack@eecs.umich.edu freeList.push_back(®isters[i]); 615636Sgblack@eecs.umich.edu } 628335Snate@binkert.org} 635636Sgblack@eecs.umich.edu 645643Sgblack@eecs.umich.eduMSHR * 655643Sgblack@eecs.umich.eduMSHRQueue::findMatch(Addr addr, bool is_secure) const 668335Snate@binkert.org{ 675643Sgblack@eecs.umich.edu MSHR::ConstIterator i = allocatedList.begin(); 685633Sgblack@eecs.umich.edu MSHR::ConstIterator end = allocatedList.end(); 695633Sgblack@eecs.umich.edu for (; i != end; ++i) { 709807Sstever@gmail.com MSHR *mshr = *i; 71 if (mshr->addr == addr && mshr->isSecure == is_secure) { 72 return mshr; 73 } 74 } 75 return NULL; 76} 77 78bool 79MSHRQueue::findMatches(Addr addr, bool is_secure, vector<MSHR*>& matches) const 80{ 81 // Need an empty vector 82 assert(matches.empty()); 83 bool retval = false; 84 MSHR::ConstIterator i = allocatedList.begin(); 85 MSHR::ConstIterator end = allocatedList.end(); 86 for (; i != end; ++i) { 87 MSHR *mshr = *i; 88 if (mshr->addr == addr && mshr->isSecure == is_secure) { 89 retval = true; 90 matches.push_back(mshr); 91 } 92 } 93 return retval; 94} 95 96 97bool 98MSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 99{ 100 pkt->pushLabel(label); 101 MSHR::ConstIterator i = allocatedList.begin(); 102 MSHR::ConstIterator end = allocatedList.end(); 103 for (; i != end; ++i) { 104 MSHR *mshr = *i; 105 if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) { 106 pkt->popLabel(); 107 return true; 108 } 109 } 110 pkt->popLabel(); 111 return false; 112} 113 114 115MSHR * 116MSHRQueue::findPending(Addr addr, int size, bool is_secure) const 117{ 118 MSHR::ConstIterator i = readyList.begin(); 119 MSHR::ConstIterator end = readyList.end(); 120 for (; i != end; ++i) { 121 MSHR *mshr = *i; 122 if (mshr->isSecure == is_secure) { 123 if (mshr->addr < addr) { 124 if (mshr->addr + mshr->size > addr) 125 return mshr; 126 } else { 127 if (addr + size > mshr->addr) 128 return mshr; 129 } 130 } 131 } 132 return NULL; 133} 134 135 136MSHR::Iterator 137MSHRQueue::addToReadyList(MSHR *mshr) 138{ 139 if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 140 return readyList.insert(readyList.end(), mshr); 141 } 142 143 MSHR::Iterator i = readyList.begin(); 144 MSHR::Iterator end = readyList.end(); 145 for (; i != end; ++i) { 146 if ((*i)->readyTime > mshr->readyTime) { 147 return readyList.insert(i, mshr); 148 } 149 } 150 assert(false); 151 return end; // keep stupid compilers happy 152} 153 154 155MSHR * 156MSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 157 Tick when, Counter order) 158{ 159 assert(!freeList.empty()); 160 MSHR *mshr = freeList.front(); 161 assert(mshr->getNumTargets() == 0); 162 freeList.pop_front(); 163 164 mshr->allocate(addr, size, pkt, when, order); 165 mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 166 mshr->readyIter = addToReadyList(mshr); 167 168 allocated += 1; 169 return mshr; 170} 171 172 173void 174MSHRQueue::deallocate(MSHR *mshr) 175{ 176 deallocateOne(mshr); 177} 178 179MSHR::Iterator 180MSHRQueue::deallocateOne(MSHR *mshr) 181{ 182 MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 183 freeList.push_front(mshr); 184 allocated--; 185 if (mshr->inService) { 186 inServiceEntries--; 187 } else { 188 readyList.erase(mshr->readyIter); 189 } 190 mshr->deallocate(); 191 if (drainManager && allocated == 0) { 192 // Notify the drain manager that we have completed draining if 193 // there are no other outstanding requests in this MSHR queue. 194 drainManager->signalDrainDone(); 195 drainManager = NULL; 196 setDrainState(Drainable::Drained); 197 } 198 return retval; 199} 200 201void 202MSHRQueue::moveToFront(MSHR *mshr) 203{ 204 if (!mshr->inService) { 205 assert(mshr == *(mshr->readyIter)); 206 readyList.erase(mshr->readyIter); 207 mshr->readyIter = readyList.insert(readyList.begin(), mshr); 208 } 209} 210 211void 212MSHRQueue::markInService(MSHR *mshr, PacketPtr pkt) 213{ 214 if (mshr->markInService(pkt)) { 215 deallocate(mshr); 216 } else { 217 readyList.erase(mshr->readyIter); 218 inServiceEntries += 1; 219 } 220} 221 222void 223MSHRQueue::markPending(MSHR *mshr) 224{ 225 assert(mshr->inService); 226 mshr->inService = false; 227 --inServiceEntries; 228 /** 229 * @ todo might want to add rerequests to front of pending list for 230 * performance. 231 */ 232 mshr->readyIter = addToReadyList(mshr); 233} 234 235void 236MSHRQueue::squash(int threadNum) 237{ 238 MSHR::Iterator i = allocatedList.begin(); 239 MSHR::Iterator end = allocatedList.end(); 240 for (; i != end;) { 241 MSHR *mshr = *i; 242 if (mshr->threadNum == threadNum) { 243 while (mshr->hasTargets()) { 244 mshr->popTarget(); 245 assert(0/*target->req->threadId()*/ == threadNum); 246 } 247 assert(!mshr->hasTargets()); 248 assert(mshr->getNumTargets()==0); 249 if (!mshr->inService) { 250 i = deallocateOne(mshr); 251 } else { 252 //mshr->pkt->flags &= ~CACHE_LINE_FILL; 253 ++i; 254 } 255 } else { 256 ++i; 257 } 258 } 259} 260 261unsigned int 262MSHRQueue::drain(DrainManager *dm) 263{ 264 if (allocated == 0) { 265 setDrainState(Drainable::Drained); 266 return 0; 267 } else { 268 drainManager = dm; 269 setDrainState(Drainable::Draining); 270 return 1; 271 } 272} 273