arm: Add support for the dc {civac, cvac, cvau, ivac} instr

This patch adds support for decoding and executing the following ARMv8
cache maintenance instructions by Virtual Address:
* dc civac: Clean and Invalidate by Virtual Address to the Point
            of Coherency
* dc cvac: Clean by Virtual Address to the Point of Coherency
* dc cvau: Clean by Virtual Address to the Point of Unification
* dc ivac: Invalidate by Virtual Addrsess to the Point of Coherency

Change-Id: I58cabda37f9636105fda1b1e84a0a04965fb5670
Reviewed-by: Sudhanshu Jha <sudhanshu.jha@arm.com>
Reviewed-by: Stephan Diestelhorst <stephan.diestelhorst@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5060
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Nikos Nikoleris
2017-01-12 17:59:44 +00:00
parent eeb36e5b6e
commit 0c0ccad525
4 changed files with 139 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2013 ARM Limited
* Copyright (c) 2011-2013,2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -52,9 +52,9 @@ class SysDC64 : public ArmStaticInst
uint64_t imm;
SysDC64(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _base, IntRegIndex _dest, uint64_t _imm)
: ArmStaticInst(mnem, _machInst, __opClass), base(_base), dest(_dest),
imm(_imm)
IntRegIndex _base, MiscRegIndex miscReg, uint64_t _imm)
: ArmStaticInst(mnem, _machInst, __opClass), base(_base),
dest((IntRegIndex)miscReg), imm(_imm)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};

View File

@@ -350,6 +350,7 @@ namespace Aarch64
if (read) {
if ((miscReg == MISCREG_DC_CIVAC_Xt) ||
(miscReg == MISCREG_DC_CVAC_Xt) ||
(miscReg == MISCREG_DC_IVAC_Xt) ||
(miscReg == MISCREG_DC_ZVA_Xt)) {
return new Unknown64(machInst);
}
@@ -365,16 +366,26 @@ namespace Aarch64
return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt);
}
uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt);
if (miscReg == MISCREG_DC_ZVA_Xt && !read)
return new Dczva(machInst, rt, (IntRegIndex) miscReg, iss);
if (read) {
StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss);
if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE])
si->setFlag(StaticInst::IsUnverifiable);
return si;
} else {
return new Msr64(machInst, miscReg, rt, iss);
switch (miscReg) {
case MISCREG_DC_ZVA_Xt:
return new Dczva(machInst, rt, miscReg, iss);
case MISCREG_DC_CVAU_Xt:
return new Dccvau(machInst, rt, miscReg, iss);
case MISCREG_DC_CVAC_Xt:
return new Dccvac(machInst, rt, miscReg, iss);
case MISCREG_DC_CIVAC_Xt:
return new Dccivac(machInst, rt, miscReg, iss);
case MISCREG_DC_IVAC_Xt:
return new Dcivac(machInst, rt, miscReg, iss);
default:
return new Msr64(machInst, miscReg, rt, iss);
}
}
} else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
std::string full_mnem = csprintf("%s %s",

View File

@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2011-2013, 2016 ARM Limited
// Copyright (c) 2011-2013, 2016-2017 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -317,7 +317,8 @@ let {{
if (flat_idx == MISCREG_DAIF ||
flat_idx == MISCREG_DC_ZVA_Xt ||
flat_idx == MISCREG_DC_CVAC_Xt ||
flat_idx == MISCREG_DC_CIVAC_Xt
flat_idx == MISCREG_DC_CIVAC_Xt ||
flat_idx == MISCREG_DC_IVAC_Xt
)
return std::make_shared<UndefinedInstruction>(
machInst, 0, EC_TRAPPED_MSR_MRS_64,
@@ -427,6 +428,117 @@ let {{
exec_output += Store64CompleteAcc.subst(msrDCZVAIop);
msrdccvau_ea_code = '''
MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
RegId(MiscRegClass, dest)).index();
CPSR cpsr = Cpsr;
ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
'''
msrdccvau_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
msrdccvau_ea_code += '''
Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POU |
ArmISA::TLB::MustBeOne;
EA = XBase;
System *sys = xc->tcBase()->getSystemPtr();
Addr op_size = sys->cacheLineSize();
EA &= ~(op_size - 1);
'''
msrDCCVAUIop = InstObjParams("dc cvau", "Dccvau", "SysDC64",
{ "ea_code" : msrdccvau_ea_code,
"memacc_code" : ";", "use_uops" : 0,
"op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
header_output += DCStore64Declare.subst(msrDCCVAUIop);
decoder_output += DCStore64Constructor.subst(msrDCCVAUIop);
exec_output += DCStore64Execute.subst(msrDCCVAUIop);
exec_output += DCStore64InitiateAcc.subst(msrDCCVAUIop);
exec_output += Store64CompleteAcc.subst(msrDCCVAUIop);
msrdccvac_ea_code = '''
MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
RegId(MiscRegClass, dest)).index();
CPSR cpsr = Cpsr;
ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
'''
msrdccvac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
msrdccvac_ea_code += '''
Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POC |
ArmISA::TLB::MustBeOne;
EA = XBase;
System *sys = xc->tcBase()->getSystemPtr();
Addr op_size = sys->cacheLineSize();
EA &= ~(op_size - 1);
'''
msrDCCVACIop = InstObjParams("dc cvac", "Dccvac", "SysDC64",
{ "ea_code" : msrdccvac_ea_code,
"memacc_code" : ";", "use_uops" : 0,
"op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
header_output += DCStore64Declare.subst(msrDCCVACIop);
decoder_output += DCStore64Constructor.subst(msrDCCVACIop);
exec_output += DCStore64Execute.subst(msrDCCVACIop);
exec_output += DCStore64InitiateAcc.subst(msrDCCVACIop);
exec_output += Store64CompleteAcc.subst(msrDCCVACIop);
msrdccivac_ea_code = '''
MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
RegId(MiscRegClass, dest)).index();
CPSR cpsr = Cpsr;
ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
'''
msrdccivac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
msrdccivac_ea_code += '''
Request::Flags memAccessFlags = Request::CLEAN |
Request::INVALIDATE | Request::DST_POC | ArmISA::TLB::MustBeOne;
EA = XBase;
System *sys = xc->tcBase()->getSystemPtr();
Addr op_size = sys->cacheLineSize();
EA &= ~(op_size - 1);
'''
msrDCCIVACIop = InstObjParams("dc civac", "Dccivac", "SysDC64",
{ "ea_code" : msrdccivac_ea_code,
"memacc_code" : ";", "use_uops" : 0,
"op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
header_output += DCStore64Declare.subst(msrDCCIVACIop);
decoder_output += DCStore64Constructor.subst(msrDCCIVACIop);
exec_output += DCStore64Execute.subst(msrDCCIVACIop);
exec_output += DCStore64InitiateAcc.subst(msrDCCIVACIop);
exec_output += Store64CompleteAcc.subst(msrDCCIVACIop);
msrdcivac_ea_code = '''
MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
RegId(MiscRegClass, dest)).index();
CPSR cpsr = Cpsr;
ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
'''
msrdcivac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false')
msrdcivac_ea_code += '''
Request::Flags memAccessFlags = Request::INVALIDATE |
Request::DST_POC | ArmISA::TLB::MustBeOne;
EA = XBase;
System *sys = xc->tcBase()->getSystemPtr();
Addr op_size = sys->cacheLineSize();
EA &= ~(op_size - 1);
'''
msrDCIVACIop = InstObjParams("dc ivac", "Dcivac", "SysDC64",
{ "ea_code" : msrdcivac_ea_code,
"memacc_code" : ";", "use_uops" : 0,
"op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']);
header_output += DCStore64Declare.subst(msrDCIVACIop);
decoder_output += DCStore64Constructor.subst(msrDCIVACIop);
exec_output += DCStore64Execute.subst(msrDCIVACIop);
exec_output += DCStore64InitiateAcc.subst(msrDCIVACIop);
exec_output += Store64CompleteAcc.subst(msrDCIVACIop);
buildDataXImmInst("msrSP", '''
if (!canWriteAArch64SysReg(

View File

@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2011-2014 ARM Limited
// Copyright (c) 2011-2014, 2017 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -256,7 +256,8 @@ def template DCStore64Declare {{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst, IntRegIndex _base, IntRegIndex _dest, uint64_t _imm);
%(class_name)s(ExtMachInst machInst, IntRegIndex _base,
MiscRegIndex _dest, uint64_t _imm);
Fault execute(ExecContext *, Trace::InstRecord *) const;
Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
@@ -270,9 +271,10 @@ def template DCStore64Declare {{
}};
def template DCStore64Constructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex _base, IntRegIndex _dest, uint64_t _imm)
%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex _base,
MiscRegIndex _dest, uint64_t _imm)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(IntRegIndex)_base, _dest, _imm)
_base, _dest, _imm)
{
%(constructor)s;
assert(!%(use_uops)d);