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(&registers[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