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