mshr.cc revision 4670
19243SN/A/* 210206Sandreas.hansson@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 39243SN/A * All rights reserved. 49243SN/A * 59243SN/A * Redistribution and use in source and binary forms, with or without 69243SN/A * modification, are permitted provided that the following conditions are 79243SN/A * met: redistributions of source code must retain the above copyright 89243SN/A * notice, this list of conditions and the following disclaimer; 99243SN/A * redistributions in binary form must reproduce the above copyright 109243SN/A * notice, this list of conditions and the following disclaimer in the 119243SN/A * documentation and/or other materials provided with the distribution; 129243SN/A * neither the name of the copyright holders nor the names of its 139243SN/A * contributors may be used to endorse or promote products derived from 149831SN/A * this software without specific prior written permission. 159831SN/A * 169831SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179243SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189243SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199243SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209243SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219243SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229243SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239243SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249243SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259243SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269243SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279243SN/A * 289243SN/A * Authors: Erik Hallnor 299243SN/A * Dave Greene 309243SN/A */ 319243SN/A 329243SN/A/** 339243SN/A * @file 349243SN/A * Miss Status and Handling Register (MSHR) definitions. 359243SN/A */ 369243SN/A 379243SN/A#include <assert.h> 389243SN/A#include <string> 399243SN/A#include <vector> 409243SN/A#include <algorithm> 419243SN/A 429967SN/A#include "mem/cache/miss/mshr.hh" 439243SN/A#include "sim/core.hh" // for curTick 449243SN/A#include "sim/host.hh" 459243SN/A#include "base/misc.hh" 469243SN/A#include "mem/cache/cache.hh" 4710146Sandreas.hansson@arm.com 489243SN/Ausing namespace std; 499243SN/A 5010146Sandreas.hansson@arm.comMSHR::MSHR() 5110146Sandreas.hansson@arm.com{ 529243SN/A inService = false; 539488SN/A ntargets = 0; 549488SN/A threadNum = -1; 559243SN/A} 569243SN/A 579243SN/Avoid 589243SN/AMSHR::allocate(Addr _addr, int _size, PacketPtr target, 599243SN/A Tick when, Counter _order) 609243SN/A{ 6110146Sandreas.hansson@arm.com addr = _addr; 629243SN/A size = _size; 639243SN/A readyTick = when; 649243SN/A order = _order; 6510146Sandreas.hansson@arm.com assert(target); 6610146Sandreas.hansson@arm.com isCacheFill = false; 6710146Sandreas.hansson@arm.com needsExclusive = target->needsExclusive(); 689243SN/A _isUncacheable = target->req->isUncacheable(); 699243SN/A inService = false; 709243SN/A threadNum = 0; 719243SN/A ntargets = 1; 729243SN/A // Don't know of a case where we would allocate a new MSHR for a 739243SN/A // snoop (mem-side request), so set cpuSide to true here. 749243SN/A targets.push_back(Target(target, when, _order, true)); 759243SN/A assert(deferredTargets.empty()); 769243SN/A deferredNeedsExclusive = false; 779243SN/A pendingInvalidate = false; 789243SN/A pendingShared = false; 799243SN/A replacedPendingUpgrade = false; 809243SN/A data = NULL; 819243SN/A} 829243SN/A 8310146Sandreas.hansson@arm.comvoid 849243SN/AMSHR::deallocate() 859243SN/A{ 869243SN/A assert(targets.empty()); 879243SN/A assert(deferredTargets.empty()); 889243SN/A assert(ntargets == 0); 899243SN/A inService = false; 909243SN/A //allocIter = NULL; 919243SN/A //readyIter = NULL; 929243SN/A} 939243SN/A 9410146Sandreas.hansson@arm.com/* 959243SN/A * Adds a target to an MSHR 969243SN/A */ 979243SN/Avoid 9810146Sandreas.hansson@arm.comMSHR::allocateTarget(PacketPtr target, Tick when, Counter _order) 999243SN/A{ 1009243SN/A if (inService) { 1019243SN/A if (!deferredTargets.empty() || pendingInvalidate || 1029243SN/A (!needsExclusive && target->needsExclusive())) { 1039243SN/A // need to put on deferred list 1049243SN/A deferredTargets.push_back(Target(target, when, _order, true)); 1059243SN/A if (target->needsExclusive()) { 1069243SN/A deferredNeedsExclusive = true; 1079243SN/A } 1089243SN/A } else { 1099243SN/A // still OK to append to outstanding request 1109243SN/A targets.push_back(Target(target, when, _order, true)); 1119243SN/A } 1129243SN/A } else { 1139243SN/A if (target->needsExclusive()) { 1149243SN/A needsExclusive = true; 1159243SN/A } 1169243SN/A 1179243SN/A targets.push_back(Target(target, when, _order, true)); 1189243SN/A } 1199243SN/A 1209243SN/A ++ntargets; 1219243SN/A} 1229243SN/A 1239243SN/Avoid 1249243SN/AMSHR::allocateSnoopTarget(PacketPtr pkt, Tick when, Counter _order) 1259243SN/A{ 1269243SN/A assert(inService); // don't bother to call otherwise 1279243SN/A 1289243SN/A if (pendingInvalidate) { 1299243SN/A // a prior snoop has already appended an invalidation, so 13010206Sandreas.hansson@arm.com // logically we don't have the block anymore... 13110206Sandreas.hansson@arm.com return; 1329243SN/A } 13310206Sandreas.hansson@arm.com 13410206Sandreas.hansson@arm.com DPRINTF(Cache, "deferred snoop on %x: %s %s\n", addr, 13510206Sandreas.hansson@arm.com needsExclusive ? "needsExclusive" : "", 13610206Sandreas.hansson@arm.com pkt->needsExclusive() ? "pkt->needsExclusive()" : ""); 13710206Sandreas.hansson@arm.com 13810206Sandreas.hansson@arm.com if (needsExclusive || pkt->needsExclusive()) { 13910206Sandreas.hansson@arm.com // actual target device (typ. PhysicalMemory) will delete the 14010206Sandreas.hansson@arm.com // packet on reception, so we need to save a copy here 1419243SN/A targets.push_back(Target(new Packet(pkt), when, _order, false)); 1429488SN/A ++ntargets; 1439969SN/A 1449488SN/A if (needsExclusive) { 1459243SN/A // We're awaiting an exclusive copy, so ownership is pending. 1469727SN/A // It's up to us to respond once the data arrives. 1479727SN/A pkt->assertMemInhibit(); 1489727SN/A } 1499727SN/A 1509243SN/A if (pkt->needsExclusive()) { 1519243SN/A // This transaction will take away our pending copy 1529243SN/A pendingInvalidate = true; 1539243SN/A } 1549243SN/A } else { 1559243SN/A // Read to a read: no conflict, so no need to record as 1569243SN/A // target, but make sure neither reader thinks he's getting an 1579243SN/A // exclusive copy 1589243SN/A pendingShared = true; 1599243SN/A pkt->assertShared(); 1609243SN/A } 1619243SN/A} 1629969SN/A 1639243SN/A 16410141SN/Abool 1659727SN/AMSHR::promoteDeferredTargets() 1669727SN/A{ 1679727SN/A if (deferredTargets.empty()) { 1689969SN/A return false; 16910141SN/A } 1709243SN/A 1719243SN/A assert(targets.empty()); 1729243SN/A targets = deferredTargets; 1739243SN/A deferredTargets.clear(); 1749831SN/A assert(targets.size() == ntargets); 1759831SN/A 1769831SN/A needsExclusive = deferredNeedsExclusive; 1779831SN/A pendingInvalidate = false; 1789831SN/A pendingShared = false; 1799831SN/A deferredNeedsExclusive = false; 1809831SN/A order = targets.front().order; 1819831SN/A readyTick = std::max(curTick, targets.front().time); 1829831SN/A 1839831SN/A return true; 1849831SN/A} 1859831SN/A 1869831SN/A 1879831SN/Avoid 1889831SN/AMSHR::handleReplacement(CacheBlk *blk, int blkSize) 1899831SN/A{ 1909831SN/A // must be an outstanding upgrade request on block we're about to 1919831SN/A // replace... 1929831SN/A assert(!blk->isWritable()); 1939831SN/A assert(needsExclusive); 1949831SN/A replacedPendingUpgrade = true; 1959243SN/A 1969243SN/A // if it's dirty, just remember what happened and allow the 1979243SN/A // writeback to continue. we'll reissue a ReadEx later whether 1989243SN/A // the upgrade succeeds or not 1999243SN/A if (blk->isDirty()) { 2009243SN/A replacedPendingUpgradeDirty = true; 2019243SN/A return; 2029243SN/A } 2039243SN/A 2049243SN/A // if not dirty, we need to save it off as it will be only valid 2059243SN/A // copy in system if upgrade is successful (and may need to be 2069243SN/A // written back then, as the current owner if any will be 2079243SN/A // invalidating its block) 2089243SN/A replacedPendingUpgradeDirty = false; 2099243SN/A data = new uint8_t[blkSize]; 2109243SN/A std::memcpy(data, blk->data, blkSize); 2119966SN/A} 2129966SN/A 2139243SN/A 2149243SN/Abool 2159967SN/AMSHR::handleFill(Packet *pkt, CacheBlk *blk) 2169243SN/A{ 2179831SN/A if (replacedPendingUpgrade) { 2189831SN/A // block was replaced while upgrade request was in service 2199967SN/A assert(pkt->cmd == MemCmd::UpgradeResp); 2209967SN/A assert(blk == NULL); 2219967SN/A assert(replacedPendingUpgrade); 2229967SN/A replacedPendingUpgrade = false; // reset 2239967SN/A if (replacedPendingUpgradeDirty) { 2249967SN/A // we wrote back the previous copy; just reissue as a ReadEx 2259967SN/A return false; 2269831SN/A } 2279831SN/A 2289831SN/A // previous copy was not dirty, but we are now owner... fake out 2299831SN/A // cache by taking saved data and converting UpgradeResp to 2309831SN/A // ReadExResp 2319832SN/A assert(data); 2329831SN/A pkt->cmd = MemCmd::ReadExResp; 2339831SN/A pkt->setData(data); 2349831SN/A delete [] data; 2359831SN/A data = NULL; 2369831SN/A } else if (pendingShared) { 2379832SN/A // we snooped another read while this read was in 2389831SN/A // service... assert shared line on its behalf 2399831SN/A pkt->assertShared(); 2409831SN/A } 2419831SN/A 2429831SN/A return true; 2439831SN/A} 2449967SN/A 2459243SN/A 2469967SN/Avoid 2479967SN/AMSHR::dump() 2489967SN/A{ 2499243SN/A ccprintf(cerr, 2509967SN/A "inService: %d thread: %d\n" 2519967SN/A "Addr: %x ntargets %d\n" 2529967SN/A "Targets:\n", 2539243SN/A inService, threadNum, addr, ntargets); 2549243SN/A 2559243SN/A TargetListIterator tar_it = targets.begin(); 2569243SN/A for (int i = 0; i < ntargets; i++) { 2579243SN/A assert(tar_it != targets.end()); 2589243SN/A 25910206Sandreas.hansson@arm.com ccprintf(cerr, "\t%d: Addr: %x cmd: %s\n", 26010206Sandreas.hansson@arm.com i, tar_it->pkt->getAddr(), tar_it->pkt->cmdString()); 2619243SN/A 2629243SN/A tar_it++; 2639243SN/A } 26410146Sandreas.hansson@arm.com ccprintf(cerr, "\n"); 2659243SN/A} 2669243SN/A 26710146Sandreas.hansson@arm.comMSHR::~MSHR() 2689243SN/A{ 2699243SN/A} 27010146Sandreas.hansson@arm.com