Refactor coherence state table initialization.
authorSteve Reinhardt <stever@eecs.umich.edu>
Sat, 21 Oct 2006 20:43:14 +0000 (13:43 -0700)
committerSteve Reinhardt <stever@eecs.umich.edu>
Sat, 21 Oct 2006 20:43:14 +0000 (13:43 -0700)
--HG--
extra : convert_revision : eb36dd2cc1463e5076f4758a59cf68cc6b2bafc5

src/mem/cache/coherence/coherence_protocol.cc
src/mem/cache/coherence/coherence_protocol.hh

index 52beb0880dd24ac21a68cea29f173672903aadfd..3d772180512f9b03f3b89edb1a0830768a01c676 100644 (file)
@@ -206,8 +206,7 @@ bool
 CoherenceProtocol::supplyTrans(BaseCache *cache, PacketPtr &pkt,
                                CacheBlk *blk,
                                MSHR *mshr,
-                               CacheBlk::State & new_state
-                               )
+                               CacheBlk::State & new_state)
 {
     return true;
 }
@@ -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
 }
 
 
index b30fb053b1f157081e804ed33541cee8c5d4636f..481277523d451895a8e5fb79947c6c50ed4fe8c4 100644 (file)
@@ -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