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;
'Fpexc': cntrlRegNC('MISCREG_FPEXC'),
'Sctlr': cntrlRegNC('MISCREG_SCTLR'),
'SevMailbox': cntrlRegNC('MISCREG_SEV_MAILBOX'),
+ 'LLSCLock': cntrlRegNC('MISCREG_LOCKFLAG'),
#Register fields for microops
'URa' : intReg('ura'),
}
}};
-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;
- }
-}};
-
* (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
*/
* ISA-specific helper functions for locked memory accesses.
*/
+#include "arch/arm/miscregs.hh"
#include "mem/request.hh"
inline void
handleLockedRead(XC *xc, Request *req)
{
+ xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf);
+ xc->setMiscReg(MISCREG_LOCKFLAG, true);
}
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;
}
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,
"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",