From 0c0ccad52595e837301eebcf8597862d9abb4f9c Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Thu, 12 Jan 2017 17:59:44 +0000 Subject: 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 Reviewed-by: Stephan Diestelhorst Reviewed-on: https://gem5-review.googlesource.com/5060 Maintainer: Andreas Sandberg Reviewed-by: Andreas Sandberg --- src/arch/arm/insts/mem64.hh | 8 +-- src/arch/arm/isa/formats/aarch64.isa | 19 ++++-- src/arch/arm/isa/insts/data64.isa | 116 ++++++++++++++++++++++++++++++++++- src/arch/arm/isa/templates/mem64.isa | 10 +-- 4 files changed, 139 insertions(+), 14 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/insts/mem64.hh b/src/arch/arm/insts/mem64.hh index 933d34576..7ad2f52eb 100644 --- a/src/arch/arm/insts/mem64.hh +++ b/src/arch/arm/insts/mem64.hh @@ -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; }; diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa index d640caf09..0179f2f1f 100644 --- a/src/arch/arm/isa/formats/aarch64.isa +++ b/src/arch/arm/isa/formats/aarch64.isa @@ -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", diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa index 887130f77..41e36d350 100644 --- a/src/arch/arm/isa/insts/data64.isa +++ b/src/arch/arm/isa/insts/data64.isa @@ -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( 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( diff --git a/src/arch/arm/isa/templates/mem64.isa b/src/arch/arm/isa/templates/mem64.isa index ff4114898..a44a3cd25 100644 --- a/src/arch/arm/isa/templates/mem64.isa +++ b/src/arch/arm/isa/templates/mem64.isa @@ -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); -- cgit v1.2.3