From: Steve Reinhardt Date: Mon, 12 Feb 2007 17:26:47 +0000 (-0800) Subject: Move store conditional result checking from SimpleAtomicCpu write X-Git-Tag: m5_2.0_beta3~204^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f78bc80bd75f6f4ebf080620b3aaeaee3b3e46cc;p=gem5.git Move store conditional result checking from SimpleAtomicCpu write 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 --- 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 @@ -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') 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); }