From 8af1eeec6f28d9722802bf1588c911711db07ddd Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 4 Apr 2011 11:42:29 -0500 Subject: [PATCH] ARM: Use CPU local lock before sending load to mem system. This change uses the locked_mem.hh header to handle implementing CLREX. It simplifies the current implementation greatly. --- src/arch/arm/isa/insts/misc.isa | 8 ++--- src/arch/arm/isa/operands.isa | 1 + src/arch/arm/isa/templates/misc.isa | 51 ----------------------------- src/arch/arm/locked_mem.hh | 34 ++++++++++++++++++- src/arch/arm/miscregs.hh | 4 ++- 5 files changed, 39 insertions(+), 59 deletions(-) diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 35df88c81..7333faef0 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -680,18 +680,14 @@ let {{ exec_output += PredOpExecute.subst(setendIop) clrexCode = ''' - unsigned memAccessFlags = Request::CLEAR_LL | - ArmISA::TLB::AlignWord | Request::LLSC; - fault = xc->read(0, (uint32_t&)Mem, memAccessFlags); + LLSCLock = 0; ''' clrexIop = InstObjParams("clrex", "Clrex","PredOp", { "code": clrexCode, "predicate_test": predicateTest },[]) - header_output += ClrexDeclare.subst(clrexIop) + header_output += BasicDeclare.subst(clrexIop) decoder_output += BasicConstructor.subst(clrexIop) exec_output += PredOpExecute.subst(clrexIop) - exec_output += ClrexInitiateAcc.subst(clrexIop) - exec_output += ClrexCompleteAcc.subst(clrexIop) isbCode = ''' fault = new FlushPipe; diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 49a860213..b497564b7 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -227,6 +227,7 @@ def operands {{ 'Fpexc': cntrlRegNC('MISCREG_FPEXC'), 'Sctlr': cntrlRegNC('MISCREG_SCTLR'), 'SevMailbox': cntrlRegNC('MISCREG_SEV_MAILBOX'), + 'LLSCLock': cntrlRegNC('MISCREG_LOCKFLAG'), #Register fields for microops 'URa' : intReg('ura'), diff --git a/src/arch/arm/isa/templates/misc.isa b/src/arch/arm/isa/templates/misc.isa index 694dc46da..212897aa0 100644 --- a/src/arch/arm/isa/templates/misc.isa +++ b/src/arch/arm/isa/templates/misc.isa @@ -402,54 +402,3 @@ def template RegImmRegShiftOpConstructor {{ } }}; -def template ClrexDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - public: - - /// Constructor. - %(class_name)s(ExtMachInst machInst); - - %(BasicExecDeclare)s - - %(InitiateAccDeclare)s - - %(CompleteAccDeclare)s - }; -}}; - -def template ClrexInitiateAcc {{ - Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Fault fault = NoFault; - %(op_decl)s; - %(op_rd)s; - - if (%(predicate_test)s) - { - if (fault == NoFault) { - unsigned memAccessFlags = Request::CLEAR_LL | - ArmISA::TLB::AlignWord | Request::LLSC; - fault = xc->read(0, (uint32_t&)Mem, memAccessFlags); - } - } else { - xc->setPredicate(false); - } - - return fault; - } -}}; - -def template ClrexCompleteAcc {{ - Fault %(class_name)s::completeAcc(PacketPtr pkt, - %(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - return NoFault; - } -}}; - diff --git a/src/arch/arm/locked_mem.hh b/src/arch/arm/locked_mem.hh index 41899273a..f902bdb49 100644 --- a/src/arch/arm/locked_mem.hh +++ b/src/arch/arm/locked_mem.hh @@ -26,7 +26,8 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Steve Reinhardt + * Authors: Ali Saidi + * Steve Reinhardt * Stephen Hines */ @@ -39,6 +40,7 @@ * ISA-specific helper functions for locked memory accesses. */ +#include "arch/arm/miscregs.hh" #include "mem/request.hh" @@ -48,6 +50,8 @@ template inline void handleLockedRead(XC *xc, Request *req) { + xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf); + xc->setMiscReg(MISCREG_LOCKFLAG, true); } @@ -55,6 +59,34 @@ template inline bool handleLockedWrite(XC *xc, Request *req) { + if (req->isSwap()) + return true; + + // Verify that the lock flag is still set and the address + // is correct + bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG); + Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR); + if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) { + // Lock flag not set or addr mismatch in CPU; + // don't even bother sending to memory system + req->setExtraData(0); + xc->setMiscReg(MISCREG_LOCKFLAG, false); + // the rest of this code is not architectural; + // it's just a debugging aid to help detect + // livelock by warning on long sequences of failed + // store conditionals + int stCondFailures = xc->readStCondFailures(); + stCondFailures++; + xc->setStCondFailures(stCondFailures); + if (stCondFailures % 100000 == 0) { + warn("context %d: %d consecutive " + "store conditional failures\n", + xc->contextId(), stCondFailures); + } + + // store conditional failed already, so don't issue it to mem + return false; + } return true; } diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 2ccd9b4c2..051cd490e 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -171,6 +171,8 @@ namespace ArmISA MISCREG_ID_ISAR4, MISCREG_ID_ISAR5, MISCREG_CPSR_MODE, + MISCREG_LOCKFLAG, + MISCREG_LOCKADDR, MISCREG_CP15_UNIMP_START, MISCREG_TCMTR = MISCREG_CP15_UNIMP_START, MISCREG_ID_PFR1, @@ -234,7 +236,7 @@ namespace ArmISA "pmceid1", "pmc_other", "pmxevcntr", "pmuserenr", "pmintenset", "pmintenclr", "id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5", - "cpsr_mode", + "cpsr_mode", "lockflag", "lockaddr", // Unimplemented below "tcmtr", "id_pfr1", "id_dfr0", "id_afr0",