summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/alpha/isa/decoder.isa9
-rw-r--r--src/arch/alpha/isa/mem.isa75
-rw-r--r--src/arch/alpha/locked_mem.hh8
-rw-r--r--src/cpu/simple/atomic.cc11
-rw-r--r--src/cpu/simple/base.hh8
5 files changed, 98 insertions, 13 deletions
diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa
index 6df47ef7a..1da6a60f1 100644
--- a/src/arch/alpha/isa/decoder.isa
+++ b/src/arch/alpha/isa/decoder.isa
@@ -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);
}
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index c0bdd2c05..3a177d990 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -350,6 +350,41 @@ def template StoreMemAccExecute {{
{
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
+ {
+ Addr EA;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -386,6 +421,40 @@ def template StoreExecute {{
{
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
+ {
+ Addr EA;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -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')
diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh
index 52fe24173..be5086bd7 100644
--- a/src/arch/alpha/locked_mem.hh
+++ b/src/arch/alpha/locked_mem.hh
@@ -35,6 +35,14 @@
* @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"
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index fa47b0eee..6a536fbcd 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -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();
}
}
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index c4853b916..a2b624139 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -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); }