Add in support for LL/SC in the O3 CPU. Needs to be fully tested.
authorKevin Lim <ktlim@umich.edu>
Mon, 23 Oct 2006 18:00:07 +0000 (14:00 -0400)
committerKevin Lim <ktlim@umich.edu>
Mon, 23 Oct 2006 18:00:07 +0000 (14:00 -0400)
src/cpu/base_dyn_inst.hh:
    Extend BaseDynInst a little bit so it can be use as a TC as well (specifically for ll/sc code).
src/cpu/base_dyn_inst_impl.hh:
    Add variable to track if the result of the instruction should be recorded.
src/cpu/o3/alpha/cpu_impl.hh:
    Clear lock flag upon hwrei.
src/cpu/o3/lsq_unit.hh:
    Use ISA specified handling of locked reads.
src/cpu/o3/lsq_unit_impl.hh:
    Use ISA specified handling of locked writes.

--HG--
extra : convert_revision : 1f5c789c35deb4b016573c02af4aab60d726c0e5

src/cpu/base_dyn_inst.hh
src/cpu/base_dyn_inst_impl.hh
src/cpu/o3/alpha/cpu_impl.hh
src/cpu/o3/lsq_unit.hh
src/cpu/o3/lsq_unit_impl.hh

index c6881095459a47b2ed0758dc4a451935b53a0e6f..4a455556648e36b5e72c66bc072be6faac280ede 100644 (file)
@@ -206,6 +206,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
      */
     Result instResult;
 
+    /** Records changes to result? */
+    bool recordResult;
+
     /** PC of this instruction. */
     Addr PC;
 
@@ -263,6 +266,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
     /** Dumps out contents of this BaseDynInst into given string. */
     void dump(std::string &outstring);
 
+    /** Read this CPU's ID. */
+    int readCpuId() { return cpu->readCpuId(); }
+
     /** Returns the fault type. */
     Fault getFault() { return fault; }
 
@@ -402,37 +408,42 @@ class BaseDynInst : public FastAlloc, public RefCounted
     /** Records an integer register being set to a value. */
     void setIntReg(const StaticInst *si, int idx, uint64_t val)
     {
-        instResult.integer = val;
+        if (recordResult)
+            instResult.integer = val;
     }
 
     /** Records an fp register being set to a value. */
     void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
     {
-        if (width == 32)
-            instResult.dbl = (double)val;
-        else if (width == 64)
-            instResult.dbl = val;
-        else
-            panic("Unsupported width!");
+        if (recordResult) {
+            if (width == 32)
+                instResult.dbl = (double)val;
+            else if (width == 64)
+                instResult.dbl = val;
+            else
+                panic("Unsupported width!");
+        }
     }
 
     /** Records an fp register being set to a value. */
     void setFloatReg(const StaticInst *si, int idx, FloatReg val)
     {
-//        instResult.fp = val;
-        instResult.dbl = (double)val;
+        if (recordResult)
+            instResult.dbl = (double)val;
     }
 
     /** Records an fp register being set to an integer value. */
     void setFloatRegBits(const StaticInst *si, int idx, uint64_t val, int width)
     {
-        instResult.integer = val;
+        if (recordResult)
+            instResult.integer = val;
     }
 
     /** Records an fp register being set to an integer value. */
     void setFloatRegBits(const StaticInst *si, int idx, uint64_t val)
     {
-        instResult.integer = val;
+        if (recordResult)
+            instResult.integer = val;
     }
 
     /** Records that one of the source registers is ready. */
@@ -624,6 +635,15 @@ class BaseDynInst : public FastAlloc, public RefCounted
 
     /** Sets iterator for this instruction in the list of all insts. */
     void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; }
+
+  public:
+    /** Returns the number of consecutive store conditional failures. */
+    unsigned readStCondFailures()
+    { return thread->storeCondFailures; }
+
+    /** Sets the number of consecutive store conditional failures. */
+    void setStCondFailures(unsigned sc_failures)
+    { thread->storeCondFailures = sc_failures; }
 };
 
 template<class Impl>
index d6cdff5c597bb5b020d63f9ae296c6b0f3585b17..2f6859de2a3c62e2c66055b7d284810d6aa25462 100644 (file)
@@ -97,6 +97,7 @@ BaseDynInst<Impl>::initVars()
     readyRegs = 0;
 
     instResult.integer = 0;
+    recordResult = true;
 
     status.reset();
 
index b7362fad914fc53d371758b59f94fe10cd568b02..8c3d7ee32956de5c72d0a42198f3bd584b54565d 100644 (file)
@@ -260,7 +260,7 @@ Fault
 AlphaO3CPU<Impl>::hwrei(unsigned tid)
 {
     // Need to clear the lock flag upon returning from an interrupt.
-    this->lockFlag = false;
+    this->setMiscReg(TheISA::Lock_Flag_DepTag, false, tid);
 
     this->thread[tid]->kernelStats->hwrei();
 
index 11a02e7c70a8bddec787b71d6c1b1b8e95b72af7..00f24f98cf67aecd5bff94bef696d3f76faa4a9f 100644 (file)
@@ -37,6 +37,7 @@
 #include <queue>
 
 #include "arch/faults.hh"
+#include "arch/locked_mem.hh"
 #include "config/full_system.hh"
 #include "base/hashmap.hh"
 #include "cpu/inst_seq.hh"
@@ -510,8 +511,12 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
 
 #if FULL_SYSTEM
     if (req->isLocked()) {
-        cpu->lockAddr = req->getPaddr();
-        cpu->lockFlag = true;
+        // Disable recording the result temporarily.  Writing to misc
+        // regs normally updates the result, but this is not the
+        // desired behavior when handling store conditionals.
+        load_inst->recordResult = false;
+        TheISA::handleLockedRead(load_inst.get(), req);
+        load_inst->recordResult = true;
     }
 #endif
 
index 3f9db912f455ffa1816d8b6a4b61a6964cb1793a..05b784a1bd7f4cc63a67f254317ea4014ae627d1 100644 (file)
@@ -29,6 +29,7 @@
  *          Korey Sewell
  */
 
+#include "arch/locked_mem.hh"
 #include "config/use_checker.hh"
 
 #include "cpu/o3/lsq.hh"
@@ -614,27 +615,24 @@ LSQUnit<Impl>::writebackStores()
 
         // @todo: Remove this SC hack once the memory system handles it.
         if (req->isLocked()) {
-            if (req->isUncacheable()) {
-                req->setScResult(2);
-            } else {
-                if (cpu->lockFlag) {
-                    req->setScResult(1);
-                    DPRINTF(LSQUnit, "Store conditional [sn:%lli] succeeded.",
-                            inst->seqNum);
-                } else {
-                    req->setScResult(0);
-                    // Hack: Instantly complete this store.
-//                    completeDataAccess(data_pkt);
-                    DPRINTF(LSQUnit, "Store conditional [sn:%lli] failed.  "
-                            "Instantly completing it.\n",
-                            inst->seqNum);
-                    WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this);
-                    wb->schedule(curTick + 1);
-                    delete state;
-                    completeStore(storeWBIdx);
-                    incrStIdx(storeWBIdx);
-                    continue;
-                }
+            // Disable recording the result temporarily.  Writing to
+            // misc regs normally updates the result, but this is not
+            // the desired behavior when handling store conditionals.
+            inst->recordResult = false;
+            bool success = TheISA::handleLockedWrite(inst.get(), req);
+            inst->recordResult = true;
+
+            if (!success) {
+                // Instantly complete this store.
+                DPRINTF(LSQUnit, "Store conditional [sn:%lli] failed.  "
+                        "Instantly completing it.\n",
+                        inst->seqNum);
+                WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this);
+                wb->schedule(curTick + 1);
+                delete state;
+                completeStore(storeWBIdx);
+                incrStIdx(storeWBIdx);
+                continue;
             }
         } else {
             // Non-store conditionals do not need a writeback.