mshr.cc revision 4902
111661Stushar@ece.gatech.edu/*
211661Stushar@ece.gatech.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
311661Stushar@ece.gatech.edu * All rights reserved.
411661Stushar@ece.gatech.edu *
511661Stushar@ece.gatech.edu * Redistribution and use in source and binary forms, with or without
611661Stushar@ece.gatech.edu * modification, are permitted provided that the following conditions are
711661Stushar@ece.gatech.edu * met: redistributions of source code must retain the above copyright
811661Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer;
911661Stushar@ece.gatech.edu * redistributions in binary form must reproduce the above copyright
1011661Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer in the
1111661Stushar@ece.gatech.edu * documentation and/or other materials provided with the distribution;
1211661Stushar@ece.gatech.edu * neither the name of the copyright holders nor the names of its
1311661Stushar@ece.gatech.edu * contributors may be used to endorse or promote products derived from
1411661Stushar@ece.gatech.edu * this software without specific prior written permission.
1511661Stushar@ece.gatech.edu *
1611661Stushar@ece.gatech.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711661Stushar@ece.gatech.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811661Stushar@ece.gatech.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911661Stushar@ece.gatech.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011661Stushar@ece.gatech.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111661Stushar@ece.gatech.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211661Stushar@ece.gatech.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311661Stushar@ece.gatech.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411661Stushar@ece.gatech.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511661Stushar@ece.gatech.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611661Stushar@ece.gatech.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711661Stushar@ece.gatech.edu *
2811661Stushar@ece.gatech.edu * Authors: Erik Hallnor
2911661Stushar@ece.gatech.edu *          Dave Greene
3011661Stushar@ece.gatech.edu */
3111661Stushar@ece.gatech.edu
3211661Stushar@ece.gatech.edu/**
3311661Stushar@ece.gatech.edu * @file
3411661Stushar@ece.gatech.edu * Miss Status and Handling Register (MSHR) definitions.
3511661Stushar@ece.gatech.edu */
3611661Stushar@ece.gatech.edu
3711661Stushar@ece.gatech.edu#include <assert.h>
3811661Stushar@ece.gatech.edu#include <string>
3911661Stushar@ece.gatech.edu#include <vector>
4011661Stushar@ece.gatech.edu#include <algorithm>
4111661Stushar@ece.gatech.edu
4211661Stushar@ece.gatech.edu#include "mem/cache/miss/mshr.hh"
4311661Stushar@ece.gatech.edu#include "sim/core.hh" // for curTick
4411661Stushar@ece.gatech.edu#include "sim/host.hh"
4511661Stushar@ece.gatech.edu#include "base/misc.hh"
4611661Stushar@ece.gatech.edu#include "mem/cache/cache.hh"
4711661Stushar@ece.gatech.edu
4811661Stushar@ece.gatech.eduusing namespace std;
4911661Stushar@ece.gatech.edu
5011661Stushar@ece.gatech.eduMSHR::MSHR()
5111661Stushar@ece.gatech.edu{
5211661Stushar@ece.gatech.edu    inService = false;
5311661Stushar@ece.gatech.edu    ntargets = 0;
5411661Stushar@ece.gatech.edu    threadNum = -1;
5511661Stushar@ece.gatech.edu}
5611661Stushar@ece.gatech.edu
5711661Stushar@ece.gatech.eduvoid
5811661Stushar@ece.gatech.eduMSHR::allocate(Addr _addr, int _size, PacketPtr target,
5911661Stushar@ece.gatech.edu               Tick whenReady, Counter _order)
6011661Stushar@ece.gatech.edu{
6111661Stushar@ece.gatech.edu    addr = _addr;
6211661Stushar@ece.gatech.edu    size = _size;
6311661Stushar@ece.gatech.edu    readyTime = whenReady;
6411661Stushar@ece.gatech.edu    order = _order;
6511661Stushar@ece.gatech.edu    assert(target);
6611661Stushar@ece.gatech.edu    isCacheFill = false;
6711661Stushar@ece.gatech.edu    needsExclusive = target->needsExclusive();
6811661Stushar@ece.gatech.edu    _isUncacheable = target->req->isUncacheable();
6911661Stushar@ece.gatech.edu    inService = false;
7011661Stushar@ece.gatech.edu    threadNum = 0;
7111661Stushar@ece.gatech.edu    ntargets = 1;
7211661Stushar@ece.gatech.edu    // Don't know of a case where we would allocate a new MSHR for a
7311661Stushar@ece.gatech.edu    // snoop (mem-side request), so set cpuSide to true here.
7411661Stushar@ece.gatech.edu    targets.push_back(Target(target, whenReady, _order, true));
7511661Stushar@ece.gatech.edu    assert(deferredTargets.empty());
7611661Stushar@ece.gatech.edu    deferredNeedsExclusive = false;
7711661Stushar@ece.gatech.edu    pendingInvalidate = false;
7811661Stushar@ece.gatech.edu    pendingShared = false;
7911661Stushar@ece.gatech.edu    data = NULL;
8011661Stushar@ece.gatech.edu}
8111661Stushar@ece.gatech.edu
8211661Stushar@ece.gatech.eduvoid
8311661Stushar@ece.gatech.eduMSHR::deallocate()
8411661Stushar@ece.gatech.edu{
8511661Stushar@ece.gatech.edu    assert(targets.empty());
8611661Stushar@ece.gatech.edu    assert(deferredTargets.empty());
8711661Stushar@ece.gatech.edu    assert(ntargets == 0);
8811661Stushar@ece.gatech.edu    inService = false;
8911661Stushar@ece.gatech.edu    //allocIter = NULL;
9011661Stushar@ece.gatech.edu    //readyIter = NULL;
9111661Stushar@ece.gatech.edu}
9211661Stushar@ece.gatech.edu
9311661Stushar@ece.gatech.edu/*
9411661Stushar@ece.gatech.edu * Adds a target to an MSHR
9511661Stushar@ece.gatech.edu */
9611661Stushar@ece.gatech.eduvoid
9711661Stushar@ece.gatech.eduMSHR::allocateTarget(PacketPtr target, Tick whenReady, Counter _order)
9811661Stushar@ece.gatech.edu{
9911661Stushar@ece.gatech.edu    if (inService) {
10011661Stushar@ece.gatech.edu        if (!deferredTargets.empty() || pendingInvalidate ||
10111661Stushar@ece.gatech.edu            (!needsExclusive && target->needsExclusive())) {
10211661Stushar@ece.gatech.edu            // need to put on deferred list
10311661Stushar@ece.gatech.edu            deferredTargets.push_back(Target(target, whenReady, _order, true));
10411661Stushar@ece.gatech.edu            if (target->needsExclusive()) {
10511661Stushar@ece.gatech.edu                deferredNeedsExclusive = true;
10611661Stushar@ece.gatech.edu            }
10711661Stushar@ece.gatech.edu        } else {
10811661Stushar@ece.gatech.edu            // still OK to append to outstanding request
10911661Stushar@ece.gatech.edu            targets.push_back(Target(target, whenReady, _order, true));
11011661Stushar@ece.gatech.edu        }
11111661Stushar@ece.gatech.edu    } else {
11211661Stushar@ece.gatech.edu        if (target->needsExclusive()) {
11311661Stushar@ece.gatech.edu            needsExclusive = true;
11411661Stushar@ece.gatech.edu        }
11511661Stushar@ece.gatech.edu
11611661Stushar@ece.gatech.edu        targets.push_back(Target(target, whenReady, _order, true));
11711661Stushar@ece.gatech.edu    }
11811661Stushar@ece.gatech.edu
11911661Stushar@ece.gatech.edu    ++ntargets;
12011661Stushar@ece.gatech.edu}
12111661Stushar@ece.gatech.edu
12211661Stushar@ece.gatech.edubool
12311661Stushar@ece.gatech.eduMSHR::handleSnoop(PacketPtr pkt, Counter _order)
12411661Stushar@ece.gatech.edu{
12511661Stushar@ece.gatech.edu    if (!inService || (pkt->isExpressSnoop() && !pkt->isDeferredSnoop())) {
12611661Stushar@ece.gatech.edu        return false;
12711661Stushar@ece.gatech.edu    }
12811661Stushar@ece.gatech.edu
12911661Stushar@ece.gatech.edu    if (pendingInvalidate) {
13011661Stushar@ece.gatech.edu        // a prior snoop has already appended an invalidation, so
13111661Stushar@ece.gatech.edu        // logically we don't have the block anymore...
13211661Stushar@ece.gatech.edu        return true;
13311661Stushar@ece.gatech.edu    }
13411661Stushar@ece.gatech.edu
13511661Stushar@ece.gatech.edu    if (needsExclusive || pkt->needsExclusive()) {
13611661Stushar@ece.gatech.edu        // actual target device (typ. PhysicalMemory) will delete the
13711661Stushar@ece.gatech.edu        // packet on reception, so we need to save a copy here
13811661Stushar@ece.gatech.edu        targets.push_back(Target(new Packet(pkt), curTick, _order, false));
13911661Stushar@ece.gatech.edu        ++ntargets;
14011661Stushar@ece.gatech.edu
14111661Stushar@ece.gatech.edu        if (needsExclusive) {
14211661Stushar@ece.gatech.edu            // We're awaiting an exclusive copy, so ownership is pending.
14311661Stushar@ece.gatech.edu            // It's up to us to respond once the data arrives.
14411661Stushar@ece.gatech.edu            pkt->assertMemInhibit();
14511661Stushar@ece.gatech.edu        }
14611661Stushar@ece.gatech.edu
14711661Stushar@ece.gatech.edu        if (pkt->needsExclusive()) {
14811661Stushar@ece.gatech.edu            // This transaction will take away our pending copy
14911661Stushar@ece.gatech.edu            pendingInvalidate = true;
15011661Stushar@ece.gatech.edu        }
15111661Stushar@ece.gatech.edu    } else {
15211661Stushar@ece.gatech.edu        // Read to a read: no conflict, so no need to record as
15311661Stushar@ece.gatech.edu        // target, but make sure neither reader thinks he's getting an
15411661Stushar@ece.gatech.edu        // exclusive copy
15511661Stushar@ece.gatech.edu        pendingShared = true;
15611661Stushar@ece.gatech.edu        pkt->assertShared();
15711661Stushar@ece.gatech.edu    }
158
159    return true;
160}
161
162
163bool
164MSHR::promoteDeferredTargets()
165{
166    if (deferredTargets.empty()) {
167        return false;
168    }
169
170    assert(targets.empty());
171    targets = deferredTargets;
172    deferredTargets.clear();
173    assert(targets.size() == ntargets);
174
175    needsExclusive = deferredNeedsExclusive;
176    pendingInvalidate = false;
177    pendingShared = false;
178    deferredNeedsExclusive = false;
179    order = targets.front().order;
180    readyTime = std::max(curTick, targets.front().readyTime);
181
182    return true;
183}
184
185
186void
187MSHR::handleFill(Packet *pkt, CacheBlk *blk)
188{
189    if (pendingShared) {
190        // we snooped another read while this read was in
191        // service... assert shared line on its behalf
192        pkt->assertShared();
193    }
194}
195
196
197void
198MSHR::dump()
199{
200    ccprintf(cerr,
201             "inService: %d thread: %d\n"
202             "Addr: %x ntargets %d\n"
203             "Targets:\n",
204             inService, threadNum, addr, ntargets);
205
206    TargetListIterator tar_it = targets.begin();
207    for (int i = 0; i < ntargets; i++) {
208        assert(tar_it != targets.end());
209
210        ccprintf(cerr, "\t%d: Addr: %x cmd: %s\n",
211                 i, tar_it->pkt->getAddr(), tar_it->pkt->cmdString());
212
213        tar_it++;
214    }
215    ccprintf(cerr, "\n");
216}
217
218MSHR::~MSHR()
219{
220}
221