Move store conditional result checking from SimpleAtomicCpu write
authorSteve Reinhardt <stever@eecs.umich.edu>
Mon, 12 Feb 2007 17:26:47 +0000 (09:26 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Mon, 12 Feb 2007 17:26:47 +0000 (09:26 -0800)
function into Alpha ISA description.  write now just generically
returns a result value if the res pointer is non-null (which means
we can only provide a res pointer if we expect a valid result
value).

--HG--
extra : convert_revision : fb1c315515787f5fbbf7d1af7e428bdbfe8148b8

src/arch/alpha/isa/decoder.isa
src/arch/alpha/isa/mem.isa
src/arch/alpha/locked_mem.hh
src/cpu/simple/atomic.cc
src/cpu/simple/base.hh

index 6df47ef7a07728741b726107b44a83cc18d50d8d..1da6a60f16e740141fbad272f7429c956f34c454 100644 (file)
@@ -84,6 +84,9 @@ decode OPCODE default Unknown::unknown() {
                         uint64_t tmp = write_result;
                         // see stq_c
                         Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
+                        if (tmp == 1) {
+                            xc->setStCondFailures(0);
+                        }
                     }}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
         0x2f: stq_c({{ Mem.uq = Ra; }},
                     {{
@@ -96,6 +99,12 @@ decode OPCODE default Unknown::unknown() {
                         // mailbox access, and we don't update the
                         // result register at all.
                         Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
+                        if (tmp == 1) {
+                            // clear failure counter... this is
+                            // non-architectural and for debugging
+                            // only.
+                            xc->setStCondFailures(0);
+                        }
                     }}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
     }
 
index c0bdd2c059e77651cc630a6f82f357112b53669e..3a177d9908f80dcdc8caf61315357e4ead67e9e2 100644 (file)
@@ -344,6 +344,41 @@ def template LoadCompleteAcc {{
 
 
 def template StoreMemAccExecute {{
+    Fault
+    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+                                   Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        EA = xc->getEA();
+
+        if (fault == NoFault) {
+            %(memacc_code)s;
+        }
+
+        if (fault == NoFault) {
+            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+                              memAccessFlags, NULL);
+            if (traceData) { traceData->setData(Mem); }
+        }
+
+        if (fault == NoFault) {
+            %(postacc_code)s;
+        }
+
+        if (fault == NoFault) {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
+def template StoreCondMemAccExecute {{
     Fault
     %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
                                    Trace::InstRecord *traceData) const
@@ -381,6 +416,40 @@ def template StoreMemAccExecute {{
 
 
 def template StoreExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+                                  Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (fault == NoFault) {
+            %(memacc_code)s;
+        }
+
+        if (fault == NoFault) {
+            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+                              memAccessFlags, NULL);
+            if (traceData) { traceData->setData(Mem); }
+        }
+
+        if (fault == NoFault) {
+            %(postacc_code)s;
+        }
+
+        if (fault == NoFault) {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
+def template StoreCondExecute {{
     Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
                                   Trace::InstRecord *traceData) const
     {
@@ -614,10 +683,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
 
     # select templates
 
-    # define aliases... most StoreCond templates are the same as the
-    # corresponding Store templates (only CompleteAcc is different).
-    StoreCondMemAccExecute = StoreMemAccExecute
-    StoreCondExecute = StoreExecute
+    # The InitiateAcc template is the same for StoreCond templates as the
+    # corresponding Store template..
     StoreCondInitiateAcc = StoreInitiateAcc
 
     memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
index 52fe241738d50898c470494afe7834f396d62b01..be5086bd7d13256e464416d47d2ce5c1e14f0639 100644 (file)
  * @file
  *
  * ISA-specific helper functions for locked memory accesses.
+ *
+ * Note that these functions are not embedded in the ISA description
+ * because they operate on the *physical* address rather than the
+ * virtual address.  In the current M5 design, the physical address is
+ * not accessible from the ISA description, only from the CPU model.
+ * Thus the CPU is responsible for calling back to the ISA (here)
+ * after the address translation has been performed to allow the ISA
+ * to do these manipulations based on the physical address.
  */
 
 #include "arch/alpha/miscregfile.hh"
index fa47b0eeee95f9e644dfeba888294e2f47c330db..6a536fbcd17377fd5950d4e12e6865fff13560b3 100644 (file)
@@ -401,15 +401,8 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
 #endif
         }
 
-        if (req->isLocked()) {
-            uint64_t scResult = req->getScResult();
-            if (scResult != 0) {
-                // clear failure counter
-                thread->setStCondFailures(0);
-            }
-            if (res) {
-                *res = req->getScResult();
-            }
+        if (res) {
+            *res = req->getScResult();
         }
     }
 
index c4853b916bebfda1c58bfd2b29c30406e3e8bddf..a2b62413997c4f4851a2ae608efc1c8a116f45e4 100644 (file)
@@ -329,6 +329,14 @@ class BaseSimpleCPU : public BaseCPU
         return thread->setMiscRegWithEffect(reg_idx, val);
     }
 
+    unsigned readStCondFailures() {
+        return thread->readStCondFailures();
+    }
+
+    void setStCondFailures(unsigned sc_failures) {
+        thread->setStCondFailures(sc_failures);
+    }
+
 #if FULL_SYSTEM
     Fault hwrei() { return thread->hwrei(); }
     void ev5_trap(Fault fault) { fault->invoke(tc); }