mshr.cc revision 4671
12391SN/A/*
22391SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32391SN/A * All rights reserved.
42391SN/A *
52391SN/A * Redistribution and use in source and binary forms, with or without
62391SN/A * modification, are permitted provided that the following conditions are
72391SN/A * met: redistributions of source code must retain the above copyright
82391SN/A * notice, this list of conditions and the following disclaimer;
92391SN/A * redistributions in binary form must reproduce the above copyright
102391SN/A * notice, this list of conditions and the following disclaimer in the
112391SN/A * documentation and/or other materials provided with the distribution;
122391SN/A * neither the name of the copyright holders nor the names of its
132391SN/A * contributors may be used to endorse or promote products derived from
142391SN/A * this software without specific prior written permission.
152391SN/A *
162391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Erik Hallnor
292391SN/A *          Dave Greene
302391SN/A */
312391SN/A
322391SN/A/**
332391SN/A * @file
342391SN/A * Miss Status and Handling Register (MSHR) definitions.
352391SN/A */
362391SN/A
374762Snate@binkert.org#include <assert.h>
384762Snate@binkert.org#include <string>
394762Snate@binkert.org#include <vector>
402391SN/A#include <algorithm>
418719SAli.Saidi@ARM.com
422462SN/A#include "mem/cache/miss/mshr.hh"
432414SN/A#include "sim/core.hh" // for curTick
442914Ssaidi@eecs.umich.edu#include "sim/host.hh"
454762Snate@binkert.org#include "base/misc.hh"
462415SN/A#include "mem/cache/cache.hh"
478719SAli.Saidi@ARM.com
482462SN/Ausing namespace std;
492391SN/A
502391SN/AMSHR::MSHR()
512391SN/A{
522462SN/A    inService = false;
532391SN/A    ntargets = 0;
546107Ssteve.reinhardt@amd.com    threadNum = -1;
556107Ssteve.reinhardt@amd.com}
562914Ssaidi@eecs.umich.edu
572413SN/Avoid
582413SN/AMSHR::allocate(Addr _addr, int _size, PacketPtr target,
592413SN/A               Tick when, Counter _order)
602413SN/A{
612413SN/A    addr = _addr;
622640Sstever@eecs.umich.edu    size = _size;
632413SN/A    readyTick = when;
642413SN/A    order = _order;
652413SN/A    assert(target);
663349Sbinkertn@umich.edu    isCacheFill = false;
672413SN/A    needsExclusive = target->needsExclusive();
683349Sbinkertn@umich.edu    _isUncacheable = target->req->isUncacheable();
692413SN/A    inService = false;
708711Sandreas.hansson@arm.com    threadNum = 0;
712413SN/A    ntargets = 1;
728711Sandreas.hansson@arm.com    // Don't know of a case where we would allocate a new MSHR for a
732413SN/A    // snoop (mem-side request), so set cpuSide to true here.
746227Snate@binkert.org    targets.push_back(Target(target, when, _order, true));
752413SN/A    assert(deferredTargets.empty());
762413SN/A    deferredNeedsExclusive = false;
772416SN/A    pendingInvalidate = false;
782416SN/A    pendingShared = false;
792413SN/A    data = NULL;
802391SN/A}
812391SN/A
822391SN/Avoid
832391SN/AMSHR::deallocate()
842391SN/A{
852391SN/A    assert(targets.empty());
863170Sstever@eecs.umich.edu    assert(deferredTargets.empty());
873170Sstever@eecs.umich.edu    assert(ntargets == 0);
883170Sstever@eecs.umich.edu    inService = false;
893170Sstever@eecs.umich.edu    //allocIter = NULL;
903170Sstever@eecs.umich.edu    //readyIter = NULL;
913170Sstever@eecs.umich.edu}
923170Sstever@eecs.umich.edu
933170Sstever@eecs.umich.edu/*
943170Sstever@eecs.umich.edu * Adds a target to an MSHR
955543Ssaidi@eecs.umich.edu */
965714Shsul@eecs.umich.eduvoid
973170Sstever@eecs.umich.eduMSHR::allocateTarget(PacketPtr target, Tick when, Counter _order)
983170Sstever@eecs.umich.edu{
993170Sstever@eecs.umich.edu    if (inService) {
1003170Sstever@eecs.umich.edu        if (!deferredTargets.empty() || pendingInvalidate ||
1015714Shsul@eecs.umich.edu            (!needsExclusive && target->needsExclusive())) {
1023170Sstever@eecs.umich.edu            // need to put on deferred list
1033170Sstever@eecs.umich.edu            deferredTargets.push_back(Target(target, when, _order, true));
1043170Sstever@eecs.umich.edu            if (target->needsExclusive()) {
1053170Sstever@eecs.umich.edu                deferredNeedsExclusive = true;
1065714Shsul@eecs.umich.edu            }
1073170Sstever@eecs.umich.edu        } else {
1083170Sstever@eecs.umich.edu            // still OK to append to outstanding request
1097733SAli.Saidi@ARM.com            targets.push_back(Target(target, when, _order, true));
1107733SAli.Saidi@ARM.com        }
1117733SAli.Saidi@ARM.com    } else {
1127733SAli.Saidi@ARM.com        if (target->needsExclusive()) {
1137733SAli.Saidi@ARM.com            needsExclusive = true;
1143170Sstever@eecs.umich.edu        }
1153170Sstever@eecs.umich.edu
1163170Sstever@eecs.umich.edu        targets.push_back(Target(target, when, _order, true));
1173170Sstever@eecs.umich.edu    }
1183170Sstever@eecs.umich.edu
1193170Sstever@eecs.umich.edu    ++ntargets;
1203170Sstever@eecs.umich.edu}
1213170Sstever@eecs.umich.edu
1224626Sstever@eecs.umich.eduvoid
1233170Sstever@eecs.umich.eduMSHR::allocateSnoopTarget(PacketPtr pkt, Tick when, Counter _order)
1243170Sstever@eecs.umich.edu{
1253170Sstever@eecs.umich.edu    assert(inService); // don't bother to call otherwise
1263170Sstever@eecs.umich.edu
1274626Sstever@eecs.umich.edu    if (pendingInvalidate) {
1283170Sstever@eecs.umich.edu        // a prior snoop has already appended an invalidation, so
1293170Sstever@eecs.umich.edu        // logically we don't have the block anymore...
1303170Sstever@eecs.umich.edu        return;
1313170Sstever@eecs.umich.edu    }
1323170Sstever@eecs.umich.edu
1333170Sstever@eecs.umich.edu    DPRINTF(Cache, "deferred snoop on %x: %s %s\n", addr,
1343170Sstever@eecs.umich.edu            needsExclusive ? "needsExclusive" : "",
1353170Sstever@eecs.umich.edu            pkt->needsExclusive() ? "pkt->needsExclusive()" : "");
1364626Sstever@eecs.umich.edu
1374626Sstever@eecs.umich.edu    if (needsExclusive || pkt->needsExclusive()) {
1383170Sstever@eecs.umich.edu        // actual target device (typ. PhysicalMemory) will delete the
1393170Sstever@eecs.umich.edu        // packet on reception, so we need to save a copy here
1406102Sgblack@eecs.umich.edu        targets.push_back(Target(new Packet(pkt), when, _order, false));
1416102Sgblack@eecs.umich.edu        ++ntargets;
1424040Ssaidi@eecs.umich.edu
1433170Sstever@eecs.umich.edu        if (needsExclusive) {
1446102Sgblack@eecs.umich.edu            // We're awaiting an exclusive copy, so ownership is pending.
1453170Sstever@eecs.umich.edu            // It's up to us to respond once the data arrives.
1463170Sstever@eecs.umich.edu            pkt->assertMemInhibit();
1474626Sstever@eecs.umich.edu        }
1483170Sstever@eecs.umich.edu
1493170Sstever@eecs.umich.edu        if (pkt->needsExclusive()) {
1503170Sstever@eecs.umich.edu            // This transaction will take away our pending copy
1513012Ssaidi@eecs.umich.edu            pendingInvalidate = true;
1522565SN/A        }
1535399Ssaidi@eecs.umich.edu    } else {
1544467Sstever@eecs.umich.edu        // Read to a read: no conflict, so no need to record as
1554467Sstever@eecs.umich.edu        // target, but make sure neither reader thinks he's getting an
1562391SN/A        // exclusive copy
1577730SAli.Saidi@ARM.com        pendingShared = true;
1587730SAli.Saidi@ARM.com        pkt->assertShared();
1598719SAli.Saidi@ARM.com    }
1608719SAli.Saidi@ARM.com}
1618719SAli.Saidi@ARM.com
1628719SAli.Saidi@ARM.com
1638719SAli.Saidi@ARM.combool
1648719SAli.Saidi@ARM.comMSHR::promoteDeferredTargets()
1658719SAli.Saidi@ARM.com{
1668719SAli.Saidi@ARM.com    if (deferredTargets.empty()) {
1678719SAli.Saidi@ARM.com        return false;
1688719SAli.Saidi@ARM.com    }
1698719SAli.Saidi@ARM.com
1708719SAli.Saidi@ARM.com    assert(targets.empty());
1718719SAli.Saidi@ARM.com    targets = deferredTargets;
1728719SAli.Saidi@ARM.com    deferredTargets.clear();
1738719SAli.Saidi@ARM.com    assert(targets.size() == ntargets);
1748719SAli.Saidi@ARM.com
1758719SAli.Saidi@ARM.com    needsExclusive = deferredNeedsExclusive;
1768719SAli.Saidi@ARM.com    pendingInvalidate = false;
1778719SAli.Saidi@ARM.com    pendingShared = false;
1788719SAli.Saidi@ARM.com    deferredNeedsExclusive = false;
1798719SAli.Saidi@ARM.com    order = targets.front().order;
1808719SAli.Saidi@ARM.com    readyTick = std::max(curTick, targets.front().time);
1812391SN/A
1827730SAli.Saidi@ARM.com    return true;
1837730SAli.Saidi@ARM.com}
1842391SN/A
1852391SN/A
1864762Snate@binkert.orgvoid
1874762Snate@binkert.orgMSHR::handleFill(Packet *pkt, CacheBlk *blk)
1882391SN/A{
1892391SN/A    if (pendingShared) {
1904762Snate@binkert.org        // we snooped another read while this read was in
1914762Snate@binkert.org        // service... assert shared line on its behalf
1924762Snate@binkert.org        pkt->assertShared();
1934762Snate@binkert.org    }
1944762Snate@binkert.org}
1954762Snate@binkert.org
1962391SN/A
1976227Snate@binkert.orgvoid
1988711Sandreas.hansson@arm.comMSHR::dump()
1992738Sstever@eecs.umich.edu{
2002541SN/A    ccprintf(cerr,
2012914Ssaidi@eecs.umich.edu             "inService: %d thread: %d\n"
2022391SN/A             "Addr: %x ntargets %d\n"
2033012Ssaidi@eecs.umich.edu             "Targets:\n",
2044626Sstever@eecs.umich.edu             inService, threadNum, addr, ntargets);
2053349Sbinkertn@umich.edu
2063349Sbinkertn@umich.edu    TargetListIterator tar_it = targets.begin();
2072391SN/A    for (int i = 0; i < ntargets; i++) {
2082391SN/A        assert(tar_it != targets.end());
2098719SAli.Saidi@ARM.com
2108719SAli.Saidi@ARM.com        ccprintf(cerr, "\t%d: Addr: %x cmd: %s\n",
2118719SAli.Saidi@ARM.com                 i, tar_it->pkt->getAddr(), tar_it->pkt->cmdString());
2128719SAli.Saidi@ARM.com
2138719SAli.Saidi@ARM.com        tar_it++;
2142391SN/A    }
2152391SN/A    ccprintf(cerr, "\n");
2162497SN/A}
2172391SN/A
2182391SN/AMSHR::~MSHR()
2192391SN/A{
220}
221