mshr_queue.cc revision 2813
12SN/A/* 210905Sandreas.sandberg@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 310905Sandreas.sandberg@arm.com * All rights reserved. 410905Sandreas.sandberg@arm.com * 510905Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 610905Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 710905Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 810905Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 910905Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1010905Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1110905Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1210905Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1310905Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 141762SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A * 282SN/A * Authors: Erik Hallnor 292SN/A */ 302SN/A 312SN/A/** @file 322SN/A * Definition of the MSHRQueue. 332SN/A */ 342SN/A 352SN/A#include "mem/cache/miss/mshr_queue.hh" 362SN/A#include "sim/eventq.hh" 372SN/A 382SN/Ausing namespace std; 392665Ssaidi@eecs.umich.edu 402760Sbinkertn@umich.eduMSHRQueue::MSHRQueue(int num_mshrs, int reserve) 412760Sbinkertn@umich.edu : numMSHRs(num_mshrs + reserve - 1), numReserve(reserve) 422665Ssaidi@eecs.umich.edu{ 4310905Sandreas.sandberg@arm.com allocated = 0; 442SN/A inServiceMSHRs = 0; 452SN/A allocatedTargets = 0; 462SN/A registers = new MSHR[numMSHRs]; 472SN/A for (int i = 0; i < numMSHRs; ++i) { 482SN/A freeList.push_back(®isters[i]); 492SN/A } 502SN/A} 512SN/A 522SN/AMSHRQueue::~MSHRQueue() 532SN/A{ 548229Snate@binkert.org delete [] registers; 552SN/A} 568229Snate@binkert.org 5710905Sandreas.sandberg@arm.comMSHR* 584841Ssaidi@eecs.umich.eduMSHRQueue::findMatch(Addr addr, int asid) const 592SN/A{ 6010459SAndreas.Sandberg@ARM.com MSHR::ConstIterator i = allocatedList.begin(); 616214Snate@binkert.org MSHR::ConstIterator end = allocatedList.end(); 622SN/A for (; i != end; ++i) { 632738Sstever@eecs.umich.edu MSHR *mshr = *i; 64395SN/A if (mshr->addr == addr) { 6510905Sandreas.sandberg@arm.com return mshr; 664000Ssaidi@eecs.umich.edu } 6711067Sandreas.sandberg@arm.com } 689983Sstever@gmail.com return NULL; 692SN/A} 7010905Sandreas.sandberg@arm.com 7110905Sandreas.sandberg@arm.combool 7210905Sandreas.sandberg@arm.comMSHRQueue::findMatches(Addr addr, int asid, vector<MSHR*>& matches) const 739048SAli.Saidi@ARM.com{ 749048SAli.Saidi@ARM.com // Need an empty vector 759056SAli.Saidi@ARM.com assert(matches.empty()); 769048SAli.Saidi@ARM.com bool retval = false; 779048SAli.Saidi@ARM.com MSHR::ConstIterator i = allocatedList.begin(); 789056SAli.Saidi@ARM.com MSHR::ConstIterator end = allocatedList.end(); 799048SAli.Saidi@ARM.com for (; i != end; ++i) { 8010930Sbrandon.potter@amd.com MSHR *mshr = *i; 819048SAli.Saidi@ARM.com if (mshr->addr == addr) { 82217SN/A retval = true; 8310905Sandreas.sandberg@arm.com matches.push_back(mshr); 84217SN/A } 8510459SAndreas.Sandberg@ARM.com } 8610905Sandreas.sandberg@arm.com return retval; 8710459SAndreas.Sandberg@ARM.com 8810459SAndreas.Sandberg@ARM.com} 8910905Sandreas.sandberg@arm.com 9010459SAndreas.Sandberg@ARM.comMSHR* 9110459SAndreas.Sandberg@ARM.comMSHRQueue::findPending(Packet * &pkt) const 92217SN/A{ 9310905Sandreas.sandberg@arm.com MSHR::ConstIterator i = pendingList.begin(); 94217SN/A MSHR::ConstIterator end = pendingList.end(); 9510459SAndreas.Sandberg@ARM.com for (; i != end; ++i) { 9610905Sandreas.sandberg@arm.com MSHR *mshr = *i; 9710459SAndreas.Sandberg@ARM.com if (mshr->addr < pkt->getAddr()) { 9810459SAndreas.Sandberg@ARM.com if (mshr->addr + mshr->pkt->getSize() > pkt->getAddr()) { 9910905Sandreas.sandberg@arm.com return mshr; 10010459SAndreas.Sandberg@ARM.com } 10110459SAndreas.Sandberg@ARM.com } else { 102217SN/A if (pkt->getAddr() + pkt->getSize() > mshr->addr) { 10311075SCurtis.Dunham@arm.com return mshr; 10411075SCurtis.Dunham@arm.com } 1056820SLisa.Hsu@amd.com } 10610459SAndreas.Sandberg@ARM.com 10710905Sandreas.sandberg@arm.com //need to check destination address for copies. 10811075SCurtis.Dunham@arm.com //TEMP NOT DOING COPIES 10911075SCurtis.Dunham@arm.com#if 0 11010459SAndreas.Sandberg@ARM.com if (mshr->pkt->cmd == Copy) { 11111075SCurtis.Dunham@arm.com Addr dest = mshr->pkt->dest; 11210459SAndreas.Sandberg@ARM.com if (dest < pkt->addr) { 11310459SAndreas.Sandberg@ARM.com if (dest + mshr->pkt->size > pkt->addr) { 1146820SLisa.Hsu@amd.com return mshr; 11510905Sandreas.sandberg@arm.com } 1166227Snate@binkert.org } else { 117217SN/A if (pkt->addr + pkt->size > dest) { 118217SN/A return mshr; 11910905Sandreas.sandberg@arm.com } 1204841Ssaidi@eecs.umich.edu } 1214841Ssaidi@eecs.umich.edu } 1224841Ssaidi@eecs.umich.edu#endif 12310905Sandreas.sandberg@arm.com } 1247948SAli.Saidi@ARM.com return NULL; 1257948SAli.Saidi@ARM.com} 1267948SAli.Saidi@ARM.com 12710905Sandreas.sandberg@arm.comMSHR* 12810905Sandreas.sandberg@arm.comMSHRQueue::allocate(Packet * &pkt, int size) 129217SN/A{ 1304841Ssaidi@eecs.umich.edu Addr aligned_addr = pkt->getAddr() & ~((Addr)size - 1); 13110905Sandreas.sandberg@arm.com MSHR *mshr = freeList.front(); 13210905Sandreas.sandberg@arm.com assert(mshr->getNumTargets() == 0); 1334841Ssaidi@eecs.umich.edu freeList.pop_front(); 1347948SAli.Saidi@ARM.com 13510905Sandreas.sandberg@arm.com if (!pkt->needsResponse()) { 13610905Sandreas.sandberg@arm.com mshr->allocateAsBuffer(pkt); 1377948SAli.Saidi@ARM.com } else { 138237SN/A assert(size !=0); 13910905Sandreas.sandberg@arm.com mshr->allocate(pkt->cmd, aligned_addr, pkt->req->getAsid(), size, pkt); 140237SN/A allocatedTargets += 1; 141217SN/A } 142217SN/A mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 143217SN/A mshr->readyIter = pendingList.insert(pendingList.end(), mshr); 144237SN/A 14510905Sandreas.sandberg@arm.com allocated += 1; 146217SN/A return mshr; 14710905Sandreas.sandberg@arm.com} 14810905Sandreas.sandberg@arm.com 149217SN/AMSHR* 150223SN/AMSHRQueue::allocateFetch(Addr addr, int asid, int size, Packet * &target) 15110905Sandreas.sandberg@arm.com{ 152223SN/A MSHR *mshr = freeList.front(); 15311068Sandreas.sandberg@arm.com assert(mshr->getNumTargets() == 0); 15411068Sandreas.sandberg@arm.com freeList.pop_front(); 15511068Sandreas.sandberg@arm.com mshr->allocate(Packet::ReadReq, addr, asid, size, target); 15611068Sandreas.sandberg@arm.com mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 15711068Sandreas.sandberg@arm.com mshr->readyIter = pendingList.insert(pendingList.end(), mshr); 15811068Sandreas.sandberg@arm.com 159223SN/A allocated += 1; 1605543Ssaidi@eecs.umich.edu return mshr; 16110905Sandreas.sandberg@arm.com} 162217SN/A 1635543Ssaidi@eecs.umich.eduMSHR* 16410905Sandreas.sandberg@arm.comMSHRQueue::allocateTargetList(Addr addr, int asid, int size) 165237SN/A{ 16610903Sandreas.sandberg@arm.com MSHR *mshr = freeList.front(); 16710905Sandreas.sandberg@arm.com assert(mshr->getNumTargets() == 0); 16810903Sandreas.sandberg@arm.com freeList.pop_front(); 16910903Sandreas.sandberg@arm.com Packet * dummy; 17010905Sandreas.sandberg@arm.com mshr->allocate(Packet::ReadReq, addr, asid, size, dummy); 17110903Sandreas.sandberg@arm.com mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 17210906Sandreas.sandberg@arm.com mshr->inService = true; 17310906Sandreas.sandberg@arm.com ++inServiceMSHRs; 17410906Sandreas.sandberg@arm.com ++allocated; 17510906Sandreas.sandberg@arm.com return mshr; 17610906Sandreas.sandberg@arm.com} 17710906Sandreas.sandberg@arm.com 17810906Sandreas.sandberg@arm.com 17910906Sandreas.sandberg@arm.comvoid 18010908Sandreas.sandberg@arm.comMSHRQueue::deallocate(MSHR* mshr) 18110908Sandreas.sandberg@arm.com{ 18210906Sandreas.sandberg@arm.com deallocateOne(mshr); 18310905Sandreas.sandberg@arm.com} 184237SN/A 1855543Ssaidi@eecs.umich.eduMSHR::Iterator 18611068Sandreas.sandberg@arm.comMSHRQueue::deallocateOne(MSHR* mshr) 18711068Sandreas.sandberg@arm.com{ 18811068Sandreas.sandberg@arm.com MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 18911068Sandreas.sandberg@arm.com freeList.push_front(mshr); 19011068Sandreas.sandberg@arm.com allocated--; 191217SN/A allocatedTargets -= mshr->getNumTargets(); 1929342SAndreas.Sandberg@arm.com if (mshr->inService) { 1932SN/A inServiceMSHRs--; 1949342SAndreas.Sandberg@arm.com } else { 19510905Sandreas.sandberg@arm.com pendingList.erase(mshr->readyIter); 19610905Sandreas.sandberg@arm.com } 19710905Sandreas.sandberg@arm.com mshr->deallocate(); 19810905Sandreas.sandberg@arm.com return retval; 19910905Sandreas.sandberg@arm.com} 20010905Sandreas.sandberg@arm.com 20110905Sandreas.sandberg@arm.comvoid 20210905Sandreas.sandberg@arm.comMSHRQueue::moveToFront(MSHR *mshr) 20310905Sandreas.sandberg@arm.com{ 20410905Sandreas.sandberg@arm.com if (!mshr->inService) { 20510905Sandreas.sandberg@arm.com assert(mshr == *(mshr->readyIter)); 20610905Sandreas.sandberg@arm.com pendingList.erase(mshr->readyIter); 20710905Sandreas.sandberg@arm.com mshr->readyIter = pendingList.insert(pendingList.begin(), mshr); 20810905Sandreas.sandberg@arm.com } 20910905Sandreas.sandberg@arm.com} 21010905Sandreas.sandberg@arm.com 21110905Sandreas.sandberg@arm.comvoid 21210905Sandreas.sandberg@arm.comMSHRQueue::markInService(MSHR* mshr) 21310905Sandreas.sandberg@arm.com{ 21410905Sandreas.sandberg@arm.com //assert(mshr == pendingList.front()); 21510905Sandreas.sandberg@arm.com if (!mshr->pkt->needsResponse()) { 2169342SAndreas.Sandberg@arm.com assert(mshr->getNumTargets() == 0); 2179342SAndreas.Sandberg@arm.com deallocate(mshr); 2189342SAndreas.Sandberg@arm.com return; 2199342SAndreas.Sandberg@arm.com } 2209342SAndreas.Sandberg@arm.com mshr->inService = true; 2212SN/A pendingList.erase(mshr->readyIter); 222395SN/A mshr->readyIter = NULL; 2232SN/A inServiceMSHRs += 1; 2242SN/A //pendingList.pop_front(); 22510905Sandreas.sandberg@arm.com} 22610905Sandreas.sandberg@arm.com 22710905Sandreas.sandberg@arm.comvoid 22810905Sandreas.sandberg@arm.comMSHRQueue::markPending(MSHR* mshr, Packet::Command cmd) 22910905Sandreas.sandberg@arm.com{ 23010905Sandreas.sandberg@arm.com assert(mshr->readyIter == NULL); 23110905Sandreas.sandberg@arm.com mshr->pkt->cmd = cmd; 23210905Sandreas.sandberg@arm.com mshr->pkt->flags &= ~SATISFIED; 23310905Sandreas.sandberg@arm.com mshr->inService = false; 23410905Sandreas.sandberg@arm.com --inServiceMSHRs; 23510905Sandreas.sandberg@arm.com /** 23610905Sandreas.sandberg@arm.com * @ todo might want to add rerequests to front of pending list for 23710905Sandreas.sandberg@arm.com * performance. 23810905Sandreas.sandberg@arm.com */ 23910905Sandreas.sandberg@arm.com mshr->readyIter = pendingList.insert(pendingList.end(), mshr); 24010905Sandreas.sandberg@arm.com} 24110905Sandreas.sandberg@arm.com 24210905Sandreas.sandberg@arm.comvoid 24310905Sandreas.sandberg@arm.comMSHRQueue::squash(int threadNum) 24410905Sandreas.sandberg@arm.com{ 24510905Sandreas.sandberg@arm.com MSHR::Iterator i = allocatedList.begin(); 24610905Sandreas.sandberg@arm.com MSHR::Iterator end = allocatedList.end(); 24710905Sandreas.sandberg@arm.com for (; i != end;) { 24810905Sandreas.sandberg@arm.com MSHR *mshr = *i; 24910905Sandreas.sandberg@arm.com if (mshr->threadNum == threadNum) { 25010905Sandreas.sandberg@arm.com while (mshr->hasTargets()) { 25110905Sandreas.sandberg@arm.com Packet * target = mshr->getTarget(); 25210905Sandreas.sandberg@arm.com mshr->popTarget(); 25310905Sandreas.sandberg@arm.com 25410905Sandreas.sandberg@arm.com assert(target->req->getThreadNum() == threadNum); 25510905Sandreas.sandberg@arm.com target = NULL; 25610905Sandreas.sandberg@arm.com } 25710905Sandreas.sandberg@arm.com assert(!mshr->hasTargets()); 25810905Sandreas.sandberg@arm.com assert(mshr->ntargets==0); 25910905Sandreas.sandberg@arm.com if (!mshr->inService) { 26010905Sandreas.sandberg@arm.com i = deallocateOne(mshr); 26110905Sandreas.sandberg@arm.com } else { 26210905Sandreas.sandberg@arm.com //mshr->pkt->flags &= ~CACHE_LINE_FILL; 26310905Sandreas.sandberg@arm.com ++i; 26410905Sandreas.sandberg@arm.com } 26510905Sandreas.sandberg@arm.com } else { 26610905Sandreas.sandberg@arm.com ++i; 26710905Sandreas.sandberg@arm.com } 26810905Sandreas.sandberg@arm.com } 26910905Sandreas.sandberg@arm.com} 2702SN/A