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:
parent
6b69890493
commit
8af1eeec6f
|
@ -680,18 +680,14 @@ let {{
|
||||||
exec_output += PredOpExecute.subst(setendIop)
|
exec_output += PredOpExecute.subst(setendIop)
|
||||||
|
|
||||||
clrexCode = '''
|
clrexCode = '''
|
||||||
unsigned memAccessFlags = Request::CLEAR_LL |
|
LLSCLock = 0;
|
||||||
ArmISA::TLB::AlignWord | Request::LLSC;
|
|
||||||
fault = xc->read(0, (uint32_t&)Mem, memAccessFlags);
|
|
||||||
'''
|
'''
|
||||||
clrexIop = InstObjParams("clrex", "Clrex","PredOp",
|
clrexIop = InstObjParams("clrex", "Clrex","PredOp",
|
||||||
{ "code": clrexCode,
|
{ "code": clrexCode,
|
||||||
"predicate_test": predicateTest },[])
|
"predicate_test": predicateTest },[])
|
||||||
header_output += ClrexDeclare.subst(clrexIop)
|
header_output += BasicDeclare.subst(clrexIop)
|
||||||
decoder_output += BasicConstructor.subst(clrexIop)
|
decoder_output += BasicConstructor.subst(clrexIop)
|
||||||
exec_output += PredOpExecute.subst(clrexIop)
|
exec_output += PredOpExecute.subst(clrexIop)
|
||||||
exec_output += ClrexInitiateAcc.subst(clrexIop)
|
|
||||||
exec_output += ClrexCompleteAcc.subst(clrexIop)
|
|
||||||
|
|
||||||
isbCode = '''
|
isbCode = '''
|
||||||
fault = new FlushPipe;
|
fault = new FlushPipe;
|
||||||
|
|
|
@ -227,6 +227,7 @@ def operands {{
|
||||||
'Fpexc': cntrlRegNC('MISCREG_FPEXC'),
|
'Fpexc': cntrlRegNC('MISCREG_FPEXC'),
|
||||||
'Sctlr': cntrlRegNC('MISCREG_SCTLR'),
|
'Sctlr': cntrlRegNC('MISCREG_SCTLR'),
|
||||||
'SevMailbox': cntrlRegNC('MISCREG_SEV_MAILBOX'),
|
'SevMailbox': cntrlRegNC('MISCREG_SEV_MAILBOX'),
|
||||||
|
'LLSCLock': cntrlRegNC('MISCREG_LOCKFLAG'),
|
||||||
|
|
||||||
#Register fields for microops
|
#Register fields for microops
|
||||||
'URa' : intReg('ura'),
|
'URa' : intReg('ura'),
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Authors: Steve Reinhardt
|
* Authors: Ali Saidi
|
||||||
|
* Steve Reinhardt
|
||||||
* Stephen Hines
|
* Stephen Hines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
* ISA-specific helper functions for locked memory accesses.
|
* ISA-specific helper functions for locked memory accesses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "arch/arm/miscregs.hh"
|
||||||
#include "mem/request.hh"
|
#include "mem/request.hh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,6 +50,8 @@ template <class XC>
|
||||||
inline void
|
inline void
|
||||||
handleLockedRead(XC *xc, Request *req)
|
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
|
inline bool
|
||||||
handleLockedWrite(XC *xc, Request *req)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,6 +171,8 @@ namespace ArmISA
|
||||||
MISCREG_ID_ISAR4,
|
MISCREG_ID_ISAR4,
|
||||||
MISCREG_ID_ISAR5,
|
MISCREG_ID_ISAR5,
|
||||||
MISCREG_CPSR_MODE,
|
MISCREG_CPSR_MODE,
|
||||||
|
MISCREG_LOCKFLAG,
|
||||||
|
MISCREG_LOCKADDR,
|
||||||
MISCREG_CP15_UNIMP_START,
|
MISCREG_CP15_UNIMP_START,
|
||||||
MISCREG_TCMTR = MISCREG_CP15_UNIMP_START,
|
MISCREG_TCMTR = MISCREG_CP15_UNIMP_START,
|
||||||
MISCREG_ID_PFR1,
|
MISCREG_ID_PFR1,
|
||||||
|
@ -234,7 +236,7 @@ namespace ArmISA
|
||||||
"pmceid1", "pmc_other", "pmxevcntr",
|
"pmceid1", "pmc_other", "pmxevcntr",
|
||||||
"pmuserenr", "pmintenset", "pmintenclr",
|
"pmuserenr", "pmintenset", "pmintenclr",
|
||||||
"id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
|
"id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
|
||||||
"cpsr_mode",
|
"cpsr_mode", "lockflag", "lockaddr",
|
||||||
// Unimplemented below
|
// Unimplemented below
|
||||||
"tcmtr",
|
"tcmtr",
|
||||||
"id_pfr1", "id_dfr0", "id_afr0",
|
"id_pfr1", "id_dfr0", "id_afr0",
|
||||||
|
|
Loading…
Reference in a new issue