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.
This commit is contained in:
Ali Saidi 2011-04-04 11:42:29 -05:00
parent 6b69890493
commit 8af1eeec6f
5 changed files with 39 additions and 59 deletions

View file

@ -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;

View file

@ -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'),

View file

@ -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;
}
}};

View file

@ -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 <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf);
xc->setMiscReg(MISCREG_LOCKFLAG, true);
}
@ -55,6 +59,34 @@ template <class XC>
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;
}

View file

@ -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",