diff options
Diffstat (limited to 'src/mem/cache/coherence')
-rw-r--r-- | src/mem/cache/coherence/coherence_protocol.cc | 277 | ||||
-rw-r--r-- | src/mem/cache/coherence/coherence_protocol.hh | 42 | ||||
-rw-r--r-- | src/mem/cache/coherence/simple_coherence.hh | 14 | ||||
-rw-r--r-- | src/mem/cache/coherence/uni_coherence.cc | 48 | ||||
-rw-r--r-- | src/mem/cache/coherence/uni_coherence.hh | 10 |
5 files changed, 164 insertions, 227 deletions
diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc index e28dda3dc..3d7721805 100644 --- a/src/mem/cache/coherence/coherence_protocol.cc +++ b/src/mem/cache/coherence/coherence_protocol.cc @@ -192,7 +192,7 @@ CoherenceProtocol::regStats() bool -CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::invalidateTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) { @@ -203,18 +203,17 @@ CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::supplyTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, - CacheBlk::State & new_state - ) + CacheBlk::State & new_state) { return true; } bool -CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -226,7 +225,7 @@ CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -238,7 +237,7 @@ CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -248,7 +247,7 @@ CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt, } bool -CoherenceProtocol::assertShared(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::assertShared(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -263,182 +262,106 @@ CoherenceProtocol::CoherenceProtocol(const string &name, 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(""); + // Python should catch this, but in case it doesn't... + if (!(protocol == "msi" || protocol == "mesi" || + protocol == "mosi" || protocol == "moesi")) { + fatal("CoherenceProtocol: unrecognized protocol %s\n", protocol); } - Packet::Command writeToSharedCmd = doUpgrades ? Packet::UpgradeReq : Packet::ReadExReq; - Packet::Command writeToSharedResp = doUpgrades ? Packet::UpgradeReq : Packet::ReadExResp; - -//@todo add in hardware prefetch to this list - if (protocol == "msi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Shared); - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans); - //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - - if (doUpgrades) { - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - } + bool hasOwned = (protocol == "mosi" || protocol == "moesi"); + bool hasExclusive = (protocol == "mesi" || protocol == "moesi"); + + if (hasOwned && !doUpgrades) { + fatal("CoherenceProtocol: ownership protocols require upgrade " + "transactions\n(write miss on owned block generates ReadExcl, " + "which will clobber dirty block)\n"); } - else if(protocol == "mesi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive); - //It will move into shared if the shared line is asserted in the - //getNewState function - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans); - //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - - if (doUpgrades) { - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - } + // set up a few shortcuts to save typing & visual clutter + typedef Packet P; + StateTransition (&tt)[stateMax+1][NUM_MEM_CMDS] = transitionTable; + + P::Command writeToSharedCmd = doUpgrades ? P::UpgradeReq : P::ReadExReq; + P::Command writeToSharedResp = doUpgrades ? P::UpgradeReq : P::ReadExResp; + + // Note that all transitions by default cause a panic. + // Override the valid transitions with the appropriate actions here. + + // + // ----- incoming requests: specify outgoing bus request ----- + // + tt[Invalid][P::ReadReq].onRequest(P::ReadReq); + // we only support write allocate right now + tt[Invalid][P::WriteReq].onRequest(P::ReadExReq); + tt[Shared][P::WriteReq].onRequest(writeToSharedCmd); + if (hasOwned) { + tt[Owned][P::WriteReq].onRequest(writeToSharedCmd); } - else if(protocol == "mosi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Shared); - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - transitionTable[Owned][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans); - //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); + // Prefetching causes a read + tt[Invalid][P::SoftPFReq].onRequest(P::ReadReq); + tt[Invalid][P::HardPFReq].onRequest(P::ReadReq); + + // + // ----- on response to given request: specify new state ----- + // + tt[Invalid][P::ReadExResp].onResponse(Modified); + tt[Shared][writeToSharedResp].onResponse(Modified); + // Go to Exclusive state on read response if we have one (will + // move into shared if the shared line is asserted in the + // getNewState function) + // + // originally had this as: + // tt[Invalid][P::ReadResp].onResponse(hasExclusive ? Exclusive: Shared); + // ...but for some reason that caused a link error... + if (hasExclusive) { + tt[Invalid][P::ReadResp].onResponse(Exclusive); + } else { + tt[Invalid][P::ReadResp].onResponse(Shared); + } + if (hasOwned) { + tt[Owned][writeToSharedResp].onResponse(Modified); } - else if(protocol == "moesi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive); - //It will move into shared if the shared line is asserted in the - //getNewState function - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - transitionTable[Owned][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans); - //Transitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); + // + // ----- bus snoop transition functions ----- + // + tt[Invalid][P::ReadReq].onSnoop(nullTransition); + tt[Invalid][P::ReadExReq].onSnoop(nullTransition); + tt[Invalid][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Invalid][P::WriteInvalidateReq].onSnoop(invalidateTrans); + tt[Shared][P::ReadReq].onSnoop(hasExclusive + ? assertShared : nullTransition); + tt[Shared][P::ReadExReq].onSnoop(invalidateTrans); + tt[Shared][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Shared][P::WriteInvalidateReq].onSnoop(invalidateTrans); + if (doUpgrades) { + tt[Invalid][P::UpgradeReq].onSnoop(nullTransition); + tt[Shared][P::UpgradeReq].onSnoop(invalidateTrans); + } + tt[Modified][P::ReadExReq].onSnoop(supplyAndInvalidateTrans); + tt[Modified][P::ReadReq].onSnoop(hasOwned + ? supplyAndGotoOwnedTrans + : supplyAndGotoSharedTrans); + tt[Modified][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Modified][P::WriteInvalidateReq].onSnoop(invalidateTrans); + + if (hasExclusive) { + tt[Exclusive][P::ReadReq].onSnoop(assertShared); + tt[Exclusive][P::ReadExReq].onSnoop(invalidateTrans); + tt[Exclusive][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Exclusive][P::WriteInvalidateReq].onSnoop(invalidateTrans); } - else { - cerr << "CoherenceProtocol: unrecognized protocol " << protocol - << endl; - fatal(""); + if (hasOwned) { + tt[Owned][P::ReadReq].onSnoop(supplyAndGotoOwnedTrans); + tt[Owned][P::ReadExReq].onSnoop(supplyAndInvalidateTrans); + tt[Owned][P::UpgradeReq].onSnoop(invalidateTrans); + tt[Owned][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Owned][P::WriteInvalidateReq].onSnoop(invalidateTrans); } + + // @todo add in hardware prefetch to this list } @@ -463,7 +386,7 @@ CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state, CacheBlk::State -CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState) +CoherenceProtocol::getNewState(PacketPtr &pkt, CacheBlk::State oldState) { CacheBlk::State state = oldState & stateMask; int cmd_idx = pkt->cmdToIndex(); @@ -488,7 +411,7 @@ CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState) bool -CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::handleBusRequest(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -518,7 +441,7 @@ CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt, } bool -CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::nullTransition(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) { @@ -530,7 +453,7 @@ CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::invalidTransition(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::invalidTransition(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) { diff --git a/src/mem/cache/coherence/coherence_protocol.hh b/src/mem/cache/coherence/coherence_protocol.hh index b5d7d80aa..481277523 100644 --- a/src/mem/cache/coherence/coherence_protocol.hh +++ b/src/mem/cache/coherence/coherence_protocol.hh @@ -89,7 +89,7 @@ class CoherenceProtocol : public SimObject * @param oldState The current block state. * @return The new state. */ - CacheBlk::State getNewState(Packet * &pkt, + CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State oldState); /** @@ -101,12 +101,12 @@ class CoherenceProtocol : public SimObject * @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, + bool handleBusRequest(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state); protected: /** Snoop function type. */ - typedef bool (*SnoopFuncType)(BaseCache *, Packet *&, CacheBlk *, + typedef bool (*SnoopFuncType)(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); // @@ -116,49 +116,49 @@ class CoherenceProtocol : public SimObject /** * Do nothing transition. */ - static bool nullTransition(BaseCache *, Packet *&, CacheBlk *, + static bool nullTransition(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Invalid transition, basically panic. */ - static bool invalidTransition(BaseCache *, Packet *&, CacheBlk *, + static bool invalidTransition(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Invalidate block, move to Invalid state. */ - static bool invalidateTrans(BaseCache *, Packet *&, CacheBlk *, + static bool invalidateTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Supply data, no state transition. */ - static bool supplyTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Supply data and go to Shared state. */ - static bool supplyAndGotoSharedTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyAndGotoSharedTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Supply data and go to Owned state. */ - static bool supplyAndGotoOwnedTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyAndGotoOwnedTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Invalidate block, supply data, and go to Invalid state. */ - static bool supplyAndInvalidateTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyAndInvalidateTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Assert the shared line for a block that is shared/exclusive. */ - static bool assertShared(BaseCache *, Packet *&, CacheBlk *, + static bool assertShared(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** @@ -211,31 +211,25 @@ class CoherenceProtocol : public SimObject friend class CoherenceProtocol::StateTransition; /** Mask to select status bits relevant to coherence protocol. */ - const static CacheBlk::State - stateMask = BlkValid | BlkWritable | BlkDirty; + static const int stateMask = BlkValid | BlkWritable | BlkDirty; /** The Modified (M) state. */ - const static CacheBlk::State - Modified = BlkValid | BlkWritable | BlkDirty; + static const int Modified = BlkValid | BlkWritable | BlkDirty; /** The Owned (O) state. */ - const static CacheBlk::State - Owned = BlkValid | BlkDirty; + static const int Owned = BlkValid | BlkDirty; /** The Exclusive (E) state. */ - const static CacheBlk::State - Exclusive = BlkValid | BlkWritable; + static const int Exclusive = BlkValid | BlkWritable; /** The Shared (S) state. */ - const static CacheBlk::State - Shared = BlkValid; + static const int Shared = BlkValid; /** The Invalid (I) state. */ - const static CacheBlk::State - Invalid = 0; + static const int 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; + static const int stateMax = stateMask; /** * The table of all possible transitions, organized by starting state and diff --git a/src/mem/cache/coherence/simple_coherence.hh b/src/mem/cache/coherence/simple_coherence.hh index a356b3ecc..5316e64b9 100644 --- a/src/mem/cache/coherence/simple_coherence.hh +++ b/src/mem/cache/coherence/simple_coherence.hh @@ -89,7 +89,7 @@ class SimpleCoherence * This policy does not forward invalidates, return NULL. * @return NULL. */ - Packet * getPacket() + PacketPtr getPacket() { return NULL; } @@ -99,7 +99,7 @@ class SimpleCoherence * @param pkt The request. * @param success True if the request was sent successfully. */ - void sendResult(Packet * &pkt, MSHR* cshr, bool success) + void sendResult(PacketPtr &pkt, MSHR* cshr, bool success) { //Don't do coherence return; @@ -112,7 +112,7 @@ class SimpleCoherence * @param current The current block state. * @return The new state. */ - CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current) + CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State current) { return protocol->getNewState(pkt, current); } @@ -124,7 +124,7 @@ class SimpleCoherence * @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, + bool handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state) { // assert(mshr == NULL); @@ -160,6 +160,12 @@ class SimpleCoherence bool allowFastWrites() { return false; } bool hasProtocol() { return true; } + + void propogateInvalidate(PacketPtr pkt, bool isTiming) + { + //For now we do nothing, asssumes simple coherence is top level of cache + return; + } }; #endif //__SIMPLE_COHERENCE_HH__ diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc index 751de4801..19230e35b 100644 --- a/src/mem/cache/coherence/uni_coherence.cc +++ b/src/mem/cache/coherence/uni_coherence.cc @@ -40,24 +40,24 @@ UniCoherence::UniCoherence() { } -Packet * +PacketPtr UniCoherence::getPacket() { - Packet* pkt = cshrs.getReq(); + PacketPtr pkt = cshrs.getReq(); return pkt; } void -UniCoherence::sendResult(Packet * &pkt, MSHR* cshr, bool success) +UniCoherence::sendResult(PacketPtr &pkt, MSHR* cshr, bool success) { if (success) { bool unblock = cshrs.isFull(); - cshrs.markInService(cshr); +// cshrs.markInService(cshr); + cshrs.deallocate(cshr); if (!cshrs.havePending()) { cache->clearSlaveRequest(Request_Coherence); } - cshrs.deallocate(cshr); if (unblock) { //since CSHRs are always used as buffers, should always get rid of one assert(!cshrs.isFull()); @@ -71,24 +71,36 @@ UniCoherence::sendResult(Packet * &pkt, MSHR* cshr, bool success) * @todo add support for returning slave requests, not doing them here. */ bool -UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr, +UniCoherence::handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state) { new_state = 0; if (pkt->isInvalidate()) { - DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n", - pkt->getAddr(), blk); - // Forward to other caches - Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1); - cshrs.allocate(tmp); - cache->setSlaveRequest(Request_Coherence, curTick); - if (cshrs.isFull()) { - cache->setBlockedForSnoop(Blocked_Coherence); + DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n", + pkt->getAddr(), blk); + } + else if (blk) { + new_state = blk->status; + } + return false; +} + +void +UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming) +{ + if (pkt->isInvalidate()) { + if (isTiming) { + // Forward to other caches + PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1); + cshrs.allocate(tmp); + cache->setSlaveRequest(Request_Coherence, curTick); + if (cshrs.isFull()) + cache->setBlockedForSnoop(Blocked_Coherence); } - } else { - if (blk) { - new_state = blk->status; + else { + PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1); + cache->cpuSidePort->sendAtomic(tmp); + delete tmp; } } - return false; } diff --git a/src/mem/cache/coherence/uni_coherence.hh b/src/mem/cache/coherence/uni_coherence.hh index 60da7a36e..44c752088 100644 --- a/src/mem/cache/coherence/uni_coherence.hh +++ b/src/mem/cache/coherence/uni_coherence.hh @@ -92,7 +92,7 @@ class UniCoherence * @param current The current block state. * @return The new state. */ - CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current) + CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State current) { if (pkt->senderState) //Blocking Buffers don't get mshrs { @@ -113,14 +113,14 @@ class UniCoherence * Return outstanding invalidate to forward. * @return The next invalidate to forward to lower levels of cache. */ - Packet * getPacket(); + PacketPtr getPacket(); /** * Was the CSHR request was sent successfully? * @param pkt The request. * @param success True if the request was sent successfully. */ - void sendResult(Packet * &pkt, MSHR* cshr, bool success); + void sendResult(PacketPtr &pkt, MSHR* cshr, bool success); /** * Handle snooped bus requests. @@ -130,7 +130,7 @@ class UniCoherence * @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, + bool handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state); /** @@ -139,6 +139,8 @@ class UniCoherence bool allowFastWrites() { return true; } bool hasProtocol() { return false; } + + void propogateInvalidate(PacketPtr pkt, bool isTiming); }; #endif //__UNI_COHERENCE_HH__ |