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
This commit is contained in:
parent
6b37bb6710
commit
f78bc80bd7
5 changed files with 98 additions and 13 deletions
|
@ -84,6 +84,9 @@ decode OPCODE default Unknown::unknown() {
|
||||||
uint64_t tmp = write_result;
|
uint64_t tmp = write_result;
|
||||||
// see stq_c
|
// see stq_c
|
||||||
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
|
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
|
||||||
|
if (tmp == 1) {
|
||||||
|
xc->setStCondFailures(0);
|
||||||
|
}
|
||||||
}}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
|
}}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
|
||||||
0x2f: stq_c({{ Mem.uq = Ra; }},
|
0x2f: stq_c({{ Mem.uq = Ra; }},
|
||||||
{{
|
{{
|
||||||
|
@ -96,6 +99,12 @@ decode OPCODE default Unknown::unknown() {
|
||||||
// mailbox access, and we don't update the
|
// mailbox access, and we don't update the
|
||||||
// result register at all.
|
// result register at all.
|
||||||
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
|
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);
|
}}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,41 @@ def template LoadCompleteAcc {{
|
||||||
|
|
||||||
|
|
||||||
def template StoreMemAccExecute {{
|
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
|
Fault
|
||||||
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
|
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
|
@ -381,6 +416,40 @@ def template StoreMemAccExecute {{
|
||||||
|
|
||||||
|
|
||||||
def template StoreExecute {{
|
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,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
|
@ -614,10 +683,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||||
|
|
||||||
# select templates
|
# select templates
|
||||||
|
|
||||||
# define aliases... most StoreCond templates are the same as the
|
# The InitiateAcc template is the same for StoreCond templates as the
|
||||||
# corresponding Store templates (only CompleteAcc is different).
|
# corresponding Store template..
|
||||||
StoreCondMemAccExecute = StoreMemAccExecute
|
|
||||||
StoreCondExecute = StoreExecute
|
|
||||||
StoreCondInitiateAcc = StoreInitiateAcc
|
StoreCondInitiateAcc = StoreInitiateAcc
|
||||||
|
|
||||||
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
|
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
|
||||||
|
|
|
@ -35,6 +35,14 @@
|
||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* ISA-specific helper functions for locked memory accesses.
|
* 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"
|
#include "arch/alpha/miscregfile.hh"
|
||||||
|
|
|
@ -401,15 +401,8 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->isLocked()) {
|
if (res) {
|
||||||
uint64_t scResult = req->getScResult();
|
*res = req->getScResult();
|
||||||
if (scResult != 0) {
|
|
||||||
// clear failure counter
|
|
||||||
thread->setStCondFailures(0);
|
|
||||||
}
|
|
||||||
if (res) {
|
|
||||||
*res = req->getScResult();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,14 @@ class BaseSimpleCPU : public BaseCPU
|
||||||
return thread->setMiscRegWithEffect(reg_idx, val);
|
return thread->setMiscRegWithEffect(reg_idx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned readStCondFailures() {
|
||||||
|
return thread->readStCondFailures();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStCondFailures(unsigned sc_failures) {
|
||||||
|
thread->setStCondFailures(sc_failures);
|
||||||
|
}
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
Fault hwrei() { return thread->hwrei(); }
|
Fault hwrei() { return thread->hwrei(); }
|
||||||
void ev5_trap(Fault fault) { fault->invoke(tc); }
|
void ev5_trap(Fault fault) { fault->invoke(tc); }
|
||||||
|
|
Loading…
Reference in a new issue