Was having difficulty with merging the cache, reverted to an early version and will add back in the patches to make it work soon.
src/mem/cache/prefetch/tagged_prefetcher_impl.hh:
Trying to merge
src/mem/cache/base_cache.cc:
src/mem/cache/base_cache.hh:
src/mem/cache/cache.cc:
src/mem/cache/cache.hh:
src/mem/cache/cache_blk.hh:
src/mem/cache/cache_builder.cc:
src/mem/cache/cache_impl.hh:
src/mem/cache/coherence/coherence_protocol.cc:
src/mem/cache/coherence/coherence_protocol.hh:
src/mem/cache/coherence/simple_coherence.hh:
src/mem/cache/coherence/uni_coherence.cc:
src/mem/cache/coherence/uni_coherence.hh:
src/mem/cache/miss/blocking_buffer.cc:
src/mem/cache/miss/blocking_buffer.hh:
src/mem/cache/miss/miss_queue.cc:
src/mem/cache/miss/miss_queue.hh:
src/mem/cache/miss/mshr.cc:
src/mem/cache/miss/mshr.hh:
src/mem/cache/miss/mshr_queue.cc:
src/mem/cache/miss/mshr_queue.hh:
src/mem/cache/prefetch/base_prefetcher.cc:
src/mem/cache/prefetch/base_prefetcher.hh:
src/mem/cache/prefetch/ghb_prefetcher.cc:
src/mem/cache/prefetch/ghb_prefetcher.hh:
src/mem/cache/prefetch/stride_prefetcher.cc:
src/mem/cache/prefetch/stride_prefetcher.hh:
src/mem/cache/prefetch/tagged_prefetcher.hh:
src/mem/cache/tags/base_tags.cc:
src/mem/cache/tags/base_tags.hh:
src/mem/cache/tags/fa_lru.cc:
src/mem/cache/tags/fa_lru.hh:
src/mem/cache/tags/iic.cc:
src/mem/cache/tags/iic.hh:
src/mem/cache/tags/lru.cc:
src/mem/cache/tags/lru.hh:
src/mem/cache/tags/repl/gen.cc:
src/mem/cache/tags/repl/gen.hh:
src/mem/cache/tags/repl/repl.cc:
src/mem/cache/tags/repl/repl.hh:
src/mem/cache/tags/split.cc:
src/mem/cache/tags/split.hh:
src/mem/cache/tags/split_blk.hh:
src/mem/cache/tags/split_lifo.cc:
src/mem/cache/tags/split_lifo.hh:
src/mem/cache/tags/split_lru.cc:
src/mem/cache/tags/split_lru.hh:
Pulling an early version of the cache into the tree due to merging issues. Will apply patches and push.
--HG--
extra : convert_revision : 3276e5fb9a6272681a1690babf2b586dd0e1f380
This commit is contained in:
566
src/mem/cache/coherence/coherence_protocol.cc
vendored
Normal file
566
src/mem/cache/coherence/coherence_protocol.cc
vendored
Normal file
@@ -0,0 +1,566 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Erik Hallnor
|
||||
* Steve Reinhardt
|
||||
* Ron Dreslinski
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definitions of CoherenceProtocol.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "mem/cache/miss/mshr.hh"
|
||||
#include "mem/cache/cache.hh"
|
||||
#include "mem/cache/coherence/coherence_protocol.hh"
|
||||
#include "sim/builder.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
CoherenceProtocol::StateTransition::StateTransition()
|
||||
: busCmd(InvalidCmd), newState(-1), snoopFunc(invalidTransition)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CoherenceProtocol::regStats()
|
||||
{
|
||||
// Even though we count all the possible transitions in the
|
||||
// requestCount and snoopCount arrays, most of these are invalid,
|
||||
// so we just select the interesting ones to print here.
|
||||
|
||||
requestCount[Invalid][Read]
|
||||
.name(name() + ".read_invalid")
|
||||
.desc("read misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Invalid][Write]
|
||||
.name(name() +".write_invalid")
|
||||
.desc("write misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Invalid][Soft_Prefetch]
|
||||
.name(name() +".swpf_invalid")
|
||||
.desc("soft prefetch misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Invalid][Hard_Prefetch]
|
||||
.name(name() +".hwpf_invalid")
|
||||
.desc("hard prefetch misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Shared][Write]
|
||||
.name(name() + ".write_shared")
|
||||
.desc("write misses to shared blocks")
|
||||
;
|
||||
|
||||
requestCount[Owned][Write]
|
||||
.name(name() + ".write_owned")
|
||||
.desc("write misses to owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Read]
|
||||
.name(name() + ".snoop_read_shared")
|
||||
.desc("read snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][ReadEx]
|
||||
.name(name() + ".snoop_readex_shared")
|
||||
.desc("readEx snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Upgrade]
|
||||
.name(name() + ".snoop_upgrade_shared")
|
||||
.desc("upgradee snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][Read]
|
||||
.name(name() + ".snoop_read_modified")
|
||||
.desc("read snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][ReadEx]
|
||||
.name(name() + ".snoop_readex_modified")
|
||||
.desc("readEx snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Read]
|
||||
.name(name() + ".snoop_read_owned")
|
||||
.desc("read snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][ReadEx]
|
||||
.name(name() + ".snoop_readex_owned")
|
||||
.desc("readEx snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Upgrade]
|
||||
.name(name() + ".snoop_upgrade_owned")
|
||||
.desc("upgrade snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][Read]
|
||||
.name(name() + ".snoop_read_exclusive")
|
||||
.desc("read snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][ReadEx]
|
||||
.name(name() + ".snoop_readex_exclusive")
|
||||
.desc("readEx snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Invalidate]
|
||||
.name(name() + ".snoop_inv_shared")
|
||||
.desc("Invalidate snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Invalidate]
|
||||
.name(name() + ".snoop_inv_owned")
|
||||
.desc("Invalidate snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][Invalidate]
|
||||
.name(name() + ".snoop_inv_exclusive")
|
||||
.desc("Invalidate snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][Invalidate]
|
||||
.name(name() + ".snoop_inv_modified")
|
||||
.desc("Invalidate snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Invalid][Invalidate]
|
||||
.name(name() + ".snoop_inv_invalid")
|
||||
.desc("Invalidate snoops on invalid blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][WriteInvalidate]
|
||||
.name(name() + ".snoop_writeinv_shared")
|
||||
.desc("WriteInvalidate snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][WriteInvalidate]
|
||||
.name(name() + ".snoop_writeinv_owned")
|
||||
.desc("WriteInvalidate snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][WriteInvalidate]
|
||||
.name(name() + ".snoop_writeinv_exclusive")
|
||||
.desc("WriteInvalidate snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][WriteInvalidate]
|
||||
.name(name() + ".snoop_writeinv_modified")
|
||||
.desc("WriteInvalidate snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Invalid][WriteInvalidate]
|
||||
.name(name() + ".snoop_writeinv_invalid")
|
||||
.desc("WriteInvalidate snoops on invalid blocks")
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk, MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
// invalidate the block
|
||||
new_state = (blk->status & ~stateMask) | Invalid;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CoherenceProtocol::supplyTrans(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk,
|
||||
MSHR *mshr,
|
||||
CacheBlk::State & new_state
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk,
|
||||
MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
new_state = (blk->status & ~stateMask) | Shared;
|
||||
pkt->flags |= SHARED_LINE;
|
||||
return supplyTrans(cache, pkt, blk, mshr, new_state);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk,
|
||||
MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
new_state = (blk->status & ~stateMask) | Owned;
|
||||
pkt->flags |= SHARED_LINE;
|
||||
return supplyTrans(cache, pkt, blk, mshr, new_state);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk,
|
||||
MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
new_state = (blk->status & ~stateMask) | Invalid;
|
||||
return supplyTrans(cache, pkt, blk, mshr, new_state);
|
||||
}
|
||||
|
||||
bool
|
||||
CoherenceProtocol::assertShared(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk,
|
||||
MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
new_state = (blk->status & ~stateMask) | Shared;
|
||||
pkt->flags |= SHARED_LINE;
|
||||
return false;
|
||||
}
|
||||
|
||||
CoherenceProtocol::CoherenceProtocol(const string &name,
|
||||
const string &protocol,
|
||||
const bool doUpgrades)
|
||||
: SimObject(name)
|
||||
{
|
||||
if ((protocol == "mosi" || protocol == "moesi") && !doUpgrades) {
|
||||
cerr << "CoherenceProtocol: ownership protocols require upgrade transactions"
|
||||
<< "(write miss on owned block generates ReadExcl, which will clobber dirty block)"
|
||||
<< endl;
|
||||
fatal("");
|
||||
}
|
||||
|
||||
Packet::CommandEnum writeToSharedCmd = doUpgrades ? Upgrade : ReadEx;
|
||||
|
||||
//@todo add in hardware prefetch to this list
|
||||
if (protocol == "msi") {
|
||||
// incoming requests: specify outgoing bus request
|
||||
transitionTable[Invalid][Read].onRequest(Read);
|
||||
transitionTable[Invalid][Write].onRequest(ReadEx);
|
||||
transitionTable[Shared][Write].onRequest(writeToSharedCmd);
|
||||
//Prefetching causes a read
|
||||
transitionTable[Invalid][Soft_Prefetch].onRequest(Read);
|
||||
transitionTable[Invalid][Hard_Prefetch].onRequest(Read);
|
||||
|
||||
// on response to given request: specify new state
|
||||
transitionTable[Invalid][Read].onResponse(Shared);
|
||||
transitionTable[Invalid][ReadEx].onResponse(Modified);
|
||||
transitionTable[Shared][writeToSharedCmd].onResponse(Modified);
|
||||
|
||||
// bus snoop transition functions
|
||||
transitionTable[Invalid][Read].onSnoop(nullTransition);
|
||||
transitionTable[Invalid][ReadEx].onSnoop(nullTransition);
|
||||
transitionTable[Shared][Read].onSnoop(nullTransition);
|
||||
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans);
|
||||
transitionTable[Modified][Read].onSnoop(supplyAndGotoSharedTrans);
|
||||
//Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
|
||||
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
|
||||
if (doUpgrades) {
|
||||
transitionTable[Invalid][Upgrade].onSnoop(nullTransition);
|
||||
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans);
|
||||
}
|
||||
}
|
||||
|
||||
else if(protocol == "mesi") {
|
||||
// incoming requests: specify outgoing bus request
|
||||
transitionTable[Invalid][Read].onRequest(Read);
|
||||
transitionTable[Invalid][Write].onRequest(ReadEx);
|
||||
transitionTable[Shared][Write].onRequest(writeToSharedCmd);
|
||||
//Prefetching causes a read
|
||||
transitionTable[Invalid][Soft_Prefetch].onRequest(Read);
|
||||
transitionTable[Invalid][Hard_Prefetch].onRequest(Read);
|
||||
|
||||
// on response to given request: specify new state
|
||||
transitionTable[Invalid][Read].onResponse(Exclusive);
|
||||
//It will move into shared if the shared line is asserted in the
|
||||
//getNewState function
|
||||
transitionTable[Invalid][ReadEx].onResponse(Modified);
|
||||
transitionTable[Shared][writeToSharedCmd].onResponse(Modified);
|
||||
|
||||
// bus snoop transition functions
|
||||
transitionTable[Invalid][Read].onSnoop(nullTransition);
|
||||
transitionTable[Invalid][ReadEx].onSnoop(nullTransition);
|
||||
transitionTable[Shared][Read].onSnoop(assertShared);
|
||||
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans);
|
||||
transitionTable[Exclusive][Read].onSnoop(assertShared);
|
||||
transitionTable[Exclusive][ReadEx].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans);
|
||||
transitionTable[Modified][Read].onSnoop(supplyAndGotoSharedTrans);
|
||||
//Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
|
||||
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Exclusive][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Exclusive][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
|
||||
if (doUpgrades) {
|
||||
transitionTable[Invalid][Upgrade].onSnoop(nullTransition);
|
||||
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans);
|
||||
}
|
||||
}
|
||||
|
||||
else if(protocol == "mosi") {
|
||||
// incoming requests: specify outgoing bus request
|
||||
transitionTable[Invalid][Read].onRequest(Read);
|
||||
transitionTable[Invalid][Write].onRequest(ReadEx);
|
||||
transitionTable[Shared][Write].onRequest(writeToSharedCmd);
|
||||
transitionTable[Owned][Write].onRequest(writeToSharedCmd);
|
||||
//Prefetching causes a read
|
||||
transitionTable[Invalid][Soft_Prefetch].onRequest(Read);
|
||||
transitionTable[Invalid][Hard_Prefetch].onRequest(Read);
|
||||
|
||||
// on response to given request: specify new state
|
||||
transitionTable[Invalid][Read].onResponse(Shared);
|
||||
transitionTable[Invalid][ReadEx].onResponse(Modified);
|
||||
transitionTable[Shared][writeToSharedCmd].onResponse(Modified);
|
||||
transitionTable[Owned][writeToSharedCmd].onResponse(Modified);
|
||||
|
||||
// bus snoop transition functions
|
||||
transitionTable[Invalid][Read].onSnoop(nullTransition);
|
||||
transitionTable[Invalid][ReadEx].onSnoop(nullTransition);
|
||||
transitionTable[Invalid][Upgrade].onSnoop(nullTransition);
|
||||
transitionTable[Shared][Read].onSnoop(assertShared);
|
||||
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans);
|
||||
transitionTable[Modified][Read].onSnoop(supplyAndGotoOwnedTrans);
|
||||
transitionTable[Owned][Read].onSnoop(supplyAndGotoOwnedTrans);
|
||||
transitionTable[Owned][ReadEx].onSnoop(supplyAndInvalidateTrans);
|
||||
transitionTable[Owned][Upgrade].onSnoop(invalidateTrans);
|
||||
//Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
|
||||
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Owned][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Owned][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
}
|
||||
|
||||
else if(protocol == "moesi") {
|
||||
// incoming requests: specify outgoing bus request
|
||||
transitionTable[Invalid][Read].onRequest(Read);
|
||||
transitionTable[Invalid][Write].onRequest(ReadEx);
|
||||
transitionTable[Shared][Write].onRequest(writeToSharedCmd);
|
||||
transitionTable[Owned][Write].onRequest(writeToSharedCmd);
|
||||
//Prefetching causes a read
|
||||
transitionTable[Invalid][Soft_Prefetch].onRequest(Read);
|
||||
transitionTable[Invalid][Hard_Prefetch].onRequest(Read);
|
||||
|
||||
// on response to given request: specify new state
|
||||
transitionTable[Invalid][Read].onResponse(Exclusive);
|
||||
//It will move into shared if the shared line is asserted in the
|
||||
//getNewState function
|
||||
transitionTable[Invalid][ReadEx].onResponse(Modified);
|
||||
transitionTable[Shared][writeToSharedCmd].onResponse(Modified);
|
||||
transitionTable[Owned][writeToSharedCmd].onResponse(Modified);
|
||||
|
||||
// bus snoop transition functions
|
||||
transitionTable[Invalid][Read].onSnoop(nullTransition);
|
||||
transitionTable[Invalid][ReadEx].onSnoop(nullTransition);
|
||||
transitionTable[Invalid][Upgrade].onSnoop(nullTransition);
|
||||
transitionTable[Shared][Read].onSnoop(assertShared);
|
||||
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans);
|
||||
transitionTable[Exclusive][Read].onSnoop(assertShared);
|
||||
transitionTable[Exclusive][ReadEx].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][Read].onSnoop(supplyAndGotoOwnedTrans);
|
||||
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans);
|
||||
transitionTable[Owned][Read].onSnoop(supplyAndGotoOwnedTrans);
|
||||
transitionTable[Owned][ReadEx].onSnoop(supplyAndInvalidateTrans);
|
||||
transitionTable[Owned][Upgrade].onSnoop(invalidateTrans);
|
||||
//Transitions on seeing a DMA (writeInv(samelevel) or DMAInv)
|
||||
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Exclusive][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Owned][Invalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Exclusive][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
transitionTable[Owned][WriteInvalidate].onSnoop(invalidateTrans);
|
||||
}
|
||||
|
||||
else {
|
||||
cerr << "CoherenceProtocol: unrecognized protocol " << protocol
|
||||
<< endl;
|
||||
fatal("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Packet::Command
|
||||
CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state,
|
||||
MSHR *mshr)
|
||||
{
|
||||
state &= stateMask;
|
||||
int cmd_idx = cmdIn.toIndex();
|
||||
|
||||
assert(0 <= state && state <= stateMax);
|
||||
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
|
||||
|
||||
Packet::Command cmdOut = transitionTable[state][cmd_idx].busCmd;
|
||||
|
||||
assert(cmdOut != InvalidCmd);
|
||||
|
||||
++requestCount[state][cmd_idx];
|
||||
|
||||
return cmdOut;
|
||||
}
|
||||
|
||||
|
||||
CacheBlk::State
|
||||
CoherenceProtocol::getNewState(const Packet * &pkt, CacheBlk::State oldState)
|
||||
{
|
||||
CacheBlk::State state = oldState & stateMask;
|
||||
int cmd_idx = pkt->cmd.toIndex();
|
||||
|
||||
assert(0 <= state && state <= stateMax);
|
||||
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
|
||||
|
||||
CacheBlk::State newState = transitionTable[state][cmd_idx].newState;
|
||||
|
||||
//Check if it's exclusive and the shared line was asserted,
|
||||
//then goto shared instead
|
||||
if (newState == Exclusive && (pkt->flags & SHARED_LINE)) {
|
||||
newState = Shared;
|
||||
}
|
||||
|
||||
assert(newState != -1);
|
||||
|
||||
//Make sure not to loose any other state information
|
||||
newState = (oldState & ~stateMask) | newState;
|
||||
return newState;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk,
|
||||
MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
if (blk == NULL) {
|
||||
// nothing to do if we don't have a block
|
||||
return false;
|
||||
}
|
||||
|
||||
CacheBlk::State state = blk->status & stateMask;
|
||||
int cmd_idx = pkt->cmd.toIndex();
|
||||
|
||||
assert(0 <= state && state <= stateMax);
|
||||
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
|
||||
|
||||
// assert(mshr == NULL); // can't currently handle outstanding requests
|
||||
//Check first if MSHR, and also insure, if there is one, that it is not in service
|
||||
assert(!mshr || mshr->inService == 0);
|
||||
++snoopCount[state][cmd_idx];
|
||||
|
||||
bool ret = transitionTable[state][cmd_idx].snoopFunc(cache, pkt, blk, mshr,
|
||||
new_state);
|
||||
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk, MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
// do nothing
|
||||
if (blk)
|
||||
new_state = blk->status;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CoherenceProtocol::invalidTransition(BaseCache *cache, Packet * &pkt,
|
||||
CacheBlk *blk, MSHR *mshr,
|
||||
CacheBlk::State & new_state)
|
||||
{
|
||||
panic("Invalid transition");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(CoherenceProtocol)
|
||||
|
||||
Param<string> protocol;
|
||||
Param<bool> do_upgrades;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(CoherenceProtocol)
|
||||
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(CoherenceProtocol)
|
||||
|
||||
INIT_PARAM(protocol, "name of coherence protocol"),
|
||||
INIT_PARAM_DFLT(do_upgrades, "use upgrade transactions?", true)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(CoherenceProtocol)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(CoherenceProtocol)
|
||||
{
|
||||
return new CoherenceProtocol(getInstanceName(), protocol,
|
||||
do_upgrades);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("CoherenceProtocol", CoherenceProtocol)
|
||||
|
||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||
263
src/mem/cache/coherence/coherence_protocol.hh
vendored
Normal file
263
src/mem/cache/coherence/coherence_protocol.hh
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Erik Hallnor
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Declaration of CoherenceProcotol a basic coherence policy.
|
||||
*/
|
||||
#ifndef __COHERENCE_PROTOCOL_HH__
|
||||
#define __COHERENCE_PROTOCOL_HH__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "sim/sim_object.hh"
|
||||
#include "mem/packet.hh"
|
||||
#include "mem/mem_cmd.hh"
|
||||
#include "mem/cache/cache_blk.hh"
|
||||
#include "base/statistics.hh"
|
||||
|
||||
class BaseCache;
|
||||
class MSHR;
|
||||
|
||||
/**
|
||||
* A simple coherence policy for the memory hierarchy. Currently implements
|
||||
* MSI, MESI, and MOESI protocols.
|
||||
*/
|
||||
class CoherenceProtocol : public SimObject
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Contruct and initialize this policy.
|
||||
* @param name The name of this policy.
|
||||
* @param protocol The string representation of the protocol to use.
|
||||
* @param doUpgrades True if bus upgrades should be used.
|
||||
*/
|
||||
CoherenceProtocol(const std::string &name, const std::string &protocol,
|
||||
const bool doUpgrades);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~CoherenceProtocol() {};
|
||||
|
||||
/**
|
||||
* Register statistics
|
||||
*/
|
||||
virtual void regStats();
|
||||
|
||||
/**
|
||||
* Get the proper bus command for the given command and status.
|
||||
* @param cmd The request's command.
|
||||
* @param status The current state of the cache block.
|
||||
* @param mshr The MSHR matching the request.
|
||||
* @return The proper bus command, as determined by the protocol.
|
||||
*/
|
||||
Packet::Command getBusCmd(Packet::Command cmd, CacheBlk::State status,
|
||||
MSHR *mshr = NULL);
|
||||
|
||||
/**
|
||||
* Return the proper state given the current state and the bus response.
|
||||
* @param req The bus response.
|
||||
* @param oldState The current block state.
|
||||
* @return The new state.
|
||||
*/
|
||||
CacheBlk::State getNewState(const Packet * &pkt,
|
||||
CacheBlk::State oldState);
|
||||
|
||||
/**
|
||||
* Handle snooped bus requests.
|
||||
* @param cache The cache that snooped the request.
|
||||
* @param req The snooped bus request.
|
||||
* @param blk The cache block corresponding to the request, if any.
|
||||
* @param mshr The MSHR corresponding to the request, if any.
|
||||
* @param new_state The new coherence state of the block.
|
||||
* @return True if the request should be satisfied locally.
|
||||
*/
|
||||
bool handleBusRequest(BaseCache *cache, Packet * &pkt, CacheBlk *blk,
|
||||
MSHR *mshr, CacheBlk::State &new_state);
|
||||
|
||||
protected:
|
||||
/** Snoop function type. */
|
||||
typedef bool (*SnoopFuncType)(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
//
|
||||
// Standard snoop transition functions
|
||||
//
|
||||
|
||||
/**
|
||||
* Do nothing transition.
|
||||
*/
|
||||
static bool nullTransition(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Invalid transition, basically panic.
|
||||
*/
|
||||
static bool invalidTransition(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Invalidate block, move to Invalid state.
|
||||
*/
|
||||
static bool invalidateTrans(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Supply data, no state transition.
|
||||
*/
|
||||
static bool supplyTrans(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Supply data and go to Shared state.
|
||||
*/
|
||||
static bool supplyAndGotoSharedTrans(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Supply data and go to Owned state.
|
||||
*/
|
||||
static bool supplyAndGotoOwnedTrans(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Invalidate block, supply data, and go to Invalid state.
|
||||
*/
|
||||
static bool supplyAndInvalidateTrans(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Assert the shared line for a block that is shared/exclusive.
|
||||
*/
|
||||
static bool assertShared(BaseCache *, Packet *&, CacheBlk *,
|
||||
MSHR *, CacheBlk::State&);
|
||||
|
||||
/**
|
||||
* Definition of protocol state transitions.
|
||||
*/
|
||||
class StateTransition
|
||||
{
|
||||
friend class CoherenceProtocol;
|
||||
|
||||
/** The bus command of this transition. */
|
||||
Packet::Command busCmd;
|
||||
/** The state to transition to. */
|
||||
int newState;
|
||||
/** The snoop function for this transition. */
|
||||
SnoopFuncType snoopFunc;
|
||||
|
||||
/**
|
||||
* Constructor, defaults to invalid transition.
|
||||
*/
|
||||
StateTransition();
|
||||
|
||||
/**
|
||||
* Initialize bus command.
|
||||
* @param cmd The bus command to use.
|
||||
*/
|
||||
void onRequest(Packet::Command cmd)
|
||||
{
|
||||
busCmd = cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transition state.
|
||||
* @param s The new state.
|
||||
*/
|
||||
void onResponse(CacheBlk::State s)
|
||||
{
|
||||
newState = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the snoop function.
|
||||
* @param f The new snoop function.
|
||||
*/
|
||||
void onSnoop(SnoopFuncType f)
|
||||
{
|
||||
snoopFunc = f;
|
||||
}
|
||||
};
|
||||
|
||||
friend class CoherenceProtocol::StateTransition;
|
||||
|
||||
/** Mask to select status bits relevant to coherence protocol. */
|
||||
const static CacheBlk::State
|
||||
stateMask = BlkValid | BlkWritable | BlkDirty;
|
||||
|
||||
/** The Modified (M) state. */
|
||||
const static CacheBlk::State
|
||||
Modified = BlkValid | BlkWritable | BlkDirty;
|
||||
/** The Owned (O) state. */
|
||||
const static CacheBlk::State
|
||||
Owned = BlkValid | BlkDirty;
|
||||
/** The Exclusive (E) state. */
|
||||
const static CacheBlk::State
|
||||
Exclusive = BlkValid | BlkWritable;
|
||||
/** The Shared (S) state. */
|
||||
const static CacheBlk::State
|
||||
Shared = BlkValid;
|
||||
/** The Invalid (I) state. */
|
||||
const static CacheBlk::State
|
||||
Invalid = 0;
|
||||
|
||||
/**
|
||||
* Maximum state encoding value (used to size transition lookup
|
||||
* table). Could be more than number of states, depends on
|
||||
* encoding of status bits.
|
||||
*/
|
||||
const static int stateMax = stateMask;
|
||||
|
||||
/**
|
||||
* The table of all possible transitions, organized by starting state and
|
||||
* request command.
|
||||
*/
|
||||
StateTransition transitionTable[stateMax+1][NUM_MEM_CMDS];
|
||||
|
||||
/**
|
||||
* @addtogroup CoherenceStatistics
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* State accesses from parent cache.
|
||||
*/
|
||||
Stats::Scalar<> requestCount[stateMax+1][NUM_MEM_CMDS];
|
||||
/**
|
||||
* State accesses from snooped requests.
|
||||
*/
|
||||
Stats::Scalar<> snoopCount[stateMax+1][NUM_MEM_CMDS];
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
};
|
||||
|
||||
#endif // __COHERENCE_PROTOCOL_HH__
|
||||
161
src/mem/cache/coherence/simple_coherence.hh
vendored
Normal file
161
src/mem/cache/coherence/simple_coherence.hh
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Erik Hallnor
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Declaration of a simple coherence policy.
|
||||
*/
|
||||
|
||||
#ifndef __SIMPLE_COHERENCE_HH__
|
||||
#define __SIMPLE_COHERENCE_HH__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "mem/packet.hh"
|
||||
#include "mem/mem_cmd.hh"
|
||||
#include "mem/cache/cache_blk.hh"
|
||||
#include "mem/cache/miss/mshr_queue.hh"
|
||||
#include "mem/cache/coherence/coherence_protocol.hh"
|
||||
|
||||
class BaseCache;
|
||||
|
||||
/**
|
||||
* A simple MP coherence policy. This policy assumes an atomic bus and only one
|
||||
* level of cache.
|
||||
*/
|
||||
class SimpleCoherence
|
||||
{
|
||||
protected:
|
||||
/** Pointer to the parent cache. */
|
||||
BaseCache *cache;
|
||||
/** Pointer to the coherence protocol. */
|
||||
CoherenceProtocol *protocol;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct and initialize this coherence policy.
|
||||
* @param _protocol The coherence protocol to use.
|
||||
*/
|
||||
SimpleCoherence(CoherenceProtocol *_protocol)
|
||||
: protocol(_protocol)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pointer to the parent cache.
|
||||
* @param _cache The parent cache.
|
||||
*/
|
||||
void setCache(BaseCache *_cache)
|
||||
{
|
||||
cache = _cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register statistics.
|
||||
* @param name The name to prepend to stat descriptions.
|
||||
*/
|
||||
void regStats(const std::string &name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This policy does not forward invalidates, return NULL.
|
||||
* @return NULL.
|
||||
*/
|
||||
Packet * getPacket()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the proper state given the current state and the bus response.
|
||||
* @param req The bus response.
|
||||
* @param current The current block state.
|
||||
* @return The new state.
|
||||
*/
|
||||
CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current)
|
||||
{
|
||||
return protocol->getNewState(pkt, current);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle snooped bus requests.
|
||||
* @param req The snooped bus request.
|
||||
* @param blk The cache block corresponding to the request, if any.
|
||||
* @param mshr The MSHR corresponding to the request, if any.
|
||||
* @param new_state Return the new state for the block.
|
||||
*/
|
||||
bool handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
|
||||
CacheBlk::State &new_state)
|
||||
{
|
||||
// assert(mshr == NULL);
|
||||
//Got rid of, there could be an MSHR, but it can't be in service
|
||||
if (blk != NULL)
|
||||
{
|
||||
if (pkt->cmd != Writeback) {
|
||||
return protocol->handleBusRequest(cache, pkt, blk, mshr,
|
||||
new_state);
|
||||
}
|
||||
else { //It is a writeback, must be ownership protocol, just keep state
|
||||
new_state = blk->status;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the proper bus command for the given command and status.
|
||||
* @param cmd The request's command.
|
||||
* @param state The current state of the cache block.
|
||||
* @return The proper bus command, as determined by the protocol.
|
||||
*/
|
||||
Packet::Command getBusCmd(Packet::Command &cmd, CacheBlk::State state)
|
||||
{
|
||||
if (cmd == Writeback) return Writeback;
|
||||
return protocol->getBusCmd(cmd, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this coherence policy can handle fast cache writes.
|
||||
*/
|
||||
bool allowFastWrites() { return false; }
|
||||
|
||||
bool hasProtocol() { return true; }
|
||||
};
|
||||
|
||||
#endif //__SIMPLE_COHERENCE_HH__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
89
src/mem/cache/coherence/uni_coherence.cc
vendored
Normal file
89
src/mem/cache/coherence/uni_coherence.cc
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Erik Hallnor
|
||||
*/
|
||||
|
||||
#include "mem/cache/coherence/uni_coherence.hh"
|
||||
#include "mem/cache/base_cache.hh"
|
||||
|
||||
#include "base/trace.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
UniCoherence::UniCoherence()
|
||||
: cshrs(50)
|
||||
{
|
||||
}
|
||||
|
||||
Packet *
|
||||
UniCoherence::getPacket()
|
||||
{
|
||||
bool unblock = cshrs.isFull();
|
||||
Packet * pkt = cshrs.getPkt();
|
||||
cshrs.markInService(pkt->senderState);
|
||||
if (!cshrs.havePending()) {
|
||||
cache->clearSlaveRequest(Request_Coherence);
|
||||
}
|
||||
if (unblock) {
|
||||
//since CSHRs are always used as buffers, should always get rid of one
|
||||
assert(!cshrs.isFull());
|
||||
cache->clearBlocked(Blocked_Coherence);
|
||||
}
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo add support for returning slave requests, not doing them here.
|
||||
*/
|
||||
bool
|
||||
UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
|
||||
CacheBlk::State &new_state)
|
||||
{
|
||||
new_state = 0;
|
||||
if (pkt->cmd.isInvalidate()) {
|
||||
DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
|
||||
pkt->paddr, blk);
|
||||
if (!cache->isTopLevel()) {
|
||||
// Forward to other caches
|
||||
Packet * tmp = new MemPkt();
|
||||
tmp->cmd = Invalidate;
|
||||
tmp->paddr = pkt->paddr;
|
||||
tmp->size = pkt->size;
|
||||
cshrs.allocate(tmp);
|
||||
cache->setSlaveRequest(Request_Coherence, curTick);
|
||||
if (cshrs.isFull()) {
|
||||
cache->setBlockedForSnoop(Blocked_Coherence);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (blk) {
|
||||
new_state = blk->status;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
136
src/mem/cache/coherence/uni_coherence.hh
vendored
Normal file
136
src/mem/cache/coherence/uni_coherence.hh
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Erik Hallnor
|
||||
*/
|
||||
|
||||
#ifndef __UNI_COHERENCE_HH__
|
||||
#define __UNI_COHERENCE_HH__
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "mem/cache/cache_blk.hh"
|
||||
#include "mem/cache/miss/mshr_queue.hh"
|
||||
#include "mem/mem_cmd.hh"
|
||||
#include "mem/packet.hh"
|
||||
|
||||
class BaseCache;
|
||||
|
||||
class UniCoherence
|
||||
{
|
||||
protected:
|
||||
/** Buffers to hold forwarded invalidates. */
|
||||
MSHRQueue cshrs;
|
||||
/** Pointer to the parent cache. */
|
||||
BaseCache *cache;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct and initialize this coherence policy.
|
||||
*/
|
||||
UniCoherence();
|
||||
|
||||
/**
|
||||
* Set the pointer to the parent cache.
|
||||
* @param _cache The parent cache.
|
||||
*/
|
||||
void setCache(BaseCache *_cache)
|
||||
{
|
||||
cache = _cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register statistics.
|
||||
* @param name The name to prepend to stat descriptions.
|
||||
*/
|
||||
void regStats(const std::string &name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Read.
|
||||
* @param cmd The request's command.
|
||||
* @param state The current state of the cache block.
|
||||
* @return The proper bus command, as determined by the protocol.
|
||||
* @todo Make changes so writebacks don't get here.
|
||||
*/
|
||||
Packet::Command getBusCmd(Packet::Command &cmd, CacheBlk::State state)
|
||||
{
|
||||
if (cmd == Hard_Prefetch && state)
|
||||
warn("Trying to issue a prefetch to a block we already have\n");
|
||||
if (cmd == Writeback)
|
||||
return Writeback;
|
||||
return Read;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just return readable and writeable.
|
||||
* @param req The bus response.
|
||||
* @param current The current block state.
|
||||
* @return The new state.
|
||||
*/
|
||||
CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current)
|
||||
{
|
||||
if (pkt->senderState) //Blocking Buffers don't get mshrs
|
||||
{
|
||||
if (pkt->senderState->originalCmd == Hard_Prefetch) {
|
||||
DPRINTF(HWPrefetch, "Marking a hardware prefetch as such in the state\n");
|
||||
return BlkHWPrefetched | BlkValid | BlkWritable;
|
||||
}
|
||||
else {
|
||||
return BlkValid | BlkWritable;
|
||||
}
|
||||
}
|
||||
//@todo What about prefetching with blocking buffers
|
||||
else
|
||||
return BlkValid | BlkWritable;
|
||||
}
|
||||
/**
|
||||
* Return outstanding invalidate to forward.
|
||||
* @return The next invalidate to forward to lower levels of cache.
|
||||
*/
|
||||
Packet * getPacket();
|
||||
|
||||
/**
|
||||
* Handle snooped bus requests.
|
||||
* @param req The snooped bus request.
|
||||
* @param blk The cache block corresponding to the request, if any.
|
||||
* @param mshr The MSHR corresponding to the request, if any.
|
||||
* @param new_state The new coherence state of the block.
|
||||
* @return True if the request should be satisfied locally.
|
||||
*/
|
||||
bool handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
|
||||
CacheBlk::State &new_state);
|
||||
|
||||
/**
|
||||
* Return true if this coherence policy can handle fast cache writes.
|
||||
*/
|
||||
bool allowFastWrites() { return true; }
|
||||
|
||||
bool hasProtocol() { return false; }
|
||||
};
|
||||
|
||||
#endif //__UNI_COHERENCE_HH__
|
||||
Reference in New Issue
Block a user