diff options
author | Nikos Nikoleris <nikos.nikoleris@arm.com> | 2017-02-07 11:35:10 +0000 |
---|---|---|
committer | Nikos Nikoleris <nikos.nikoleris@arm.com> | 2017-12-05 11:47:01 +0000 |
commit | eeb36e5b6e81c6b9ea6a0c3c97573e762e58ae05 (patch) | |
tree | 9ea079dc4bc5b04cfc4b84a32c06225670be69dd /src/arch/arm/isa/insts | |
parent | b9edb351454c2601070fb9432f23fc3914eb33c1 (diff) | |
download | gem5-eeb36e5b6e81c6b9ea6a0c3c97573e762e58ae05.tar.xz |
arm: Add support for the mcr dc{ic,i,c}mvac, dccmvau instructions
This patch adds support for the ARMv7 cache maintenance
intructions:
* mcr dccmvac cleans a VA to the PoC
* mcr dcimvac invalidates a VA to the PoC
* mcr dccimvac cleans and invalidates a VA to the PoC
* mcr dccmvau cleans a VA to the PoU
Change-Id: I6511f203039ca145cc9128ddf61d09d6d7e40c10
Reviewed-by: Stephan Diestelhorst <stephan.diestelhorst@arm.com>
Reviewed-by: Anouk Van Laer <anouk.vanlaer@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5059
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Diffstat (limited to 'src/arch/arm/isa/insts')
-rw-r--r-- | src/arch/arm/isa/insts/misc.isa | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 80ad6cdf4..ef0a6709e 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -1063,6 +1063,106 @@ let {{ decoder_output += BasicConstructor.subst(clrexIop) exec_output += PredOpExecute.subst(clrexIop) + McrDcCheckCode = ''' + int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase()); + MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId( + RegId(MiscRegClass, preFlatDest)).index(); + bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, + Hcptr, imm); + bool can_write, undefined; + std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); + + // if we're in non secure PL1 mode then we can trap regardless + // of whether the register is accessible, in other modes we + // trap if only if the register IS accessible. + if (undefined || (!can_write & !(hypTrap & !inUserMode(Cpsr) & + !inSecureState(Scr, Cpsr)))) { + return std::make_shared<UndefinedInstruction>(machInst, false, + mnemonic); + } + if (hypTrap) { + return std::make_shared<HypervisorTrap>(machInst, imm, + EC_TRAPPED_CP15_MCR_MRC); + } + ''' + + McrDcimvacCode = ''' + const Request::Flags memAccessFlags(ArmISA::TLB::MustBeOne | + Request::INVALIDATE | + Request::DST_POC); + EA = Op1; + ''' + McrDcimvacIop = InstObjParams("mcr dcimvac", "McrDcimvac", + "MiscRegRegImmMemOp", + {"memacc_code": McrDcCheckCode, + "postacc_code": "", + "ea_code": McrDcimvacCode, + "predicate_test": predicateTest}, + ['IsMemRef', 'IsStore']) + header_output += MiscRegRegImmMemOpDeclare.subst(McrDcimvacIop) + decoder_output += MiscRegRegImmOpConstructor.subst(McrDcimvacIop) + exec_output += Mcr15Execute.subst(McrDcimvacIop) + \ + Mcr15InitiateAcc.subst(McrDcimvacIop) + \ + Mcr15CompleteAcc.subst(McrDcimvacIop) + + McrDccmvacCode = ''' + const Request::Flags memAccessFlags(ArmISA::TLB::MustBeOne | + Request::CLEAN | + Request::DST_POC); + EA = Op1; + ''' + McrDccmvacIop = InstObjParams("mcr dccmvac", "McrDccmvac", + "MiscRegRegImmMemOp", + {"memacc_code": McrDcCheckCode, + "postacc_code": "", + "ea_code": McrDccmvacCode, + "predicate_test": predicateTest}, + ['IsMemRef', 'IsStore']) + header_output += MiscRegRegImmMemOpDeclare.subst(McrDccmvacIop) + decoder_output += MiscRegRegImmOpConstructor.subst(McrDccmvacIop) + exec_output += Mcr15Execute.subst(McrDccmvacIop) + \ + Mcr15InitiateAcc.subst(McrDccmvacIop) + \ + Mcr15CompleteAcc.subst(McrDccmvacIop) + + McrDccmvauCode = ''' + const Request::Flags memAccessFlags(ArmISA::TLB::MustBeOne | + Request::CLEAN | + Request::DST_POU); + EA = Op1; + ''' + McrDccmvauIop = InstObjParams("mcr dccmvau", "McrDccmvau", + "MiscRegRegImmMemOp", + {"memacc_code": McrDcCheckCode, + "postacc_code": "", + "ea_code": McrDccmvauCode, + "predicate_test": predicateTest}, + ['IsMemRef', 'IsStore']) + header_output += MiscRegRegImmMemOpDeclare.subst(McrDccmvauIop) + decoder_output += MiscRegRegImmOpConstructor.subst(McrDccmvauIop) + exec_output += Mcr15Execute.subst(McrDccmvauIop) + \ + Mcr15InitiateAcc.subst(McrDccmvauIop) + \ + Mcr15CompleteAcc.subst(McrDccmvauIop) + + McrDccimvacCode = ''' + const Request::Flags memAccessFlags(ArmISA::TLB::MustBeOne | + Request::CLEAN | + Request::INVALIDATE | + Request::DST_POC); + EA = Op1; + ''' + McrDccimvacIop = InstObjParams("mcr dccimvac", "McrDccimvac", + "MiscRegRegImmMemOp", + {"memacc_code": McrDcCheckCode, + "postacc_code": "", + "ea_code": McrDccimvacCode, + "predicate_test": predicateTest}, + ['IsMemRef', 'IsStore']) + header_output += MiscRegRegImmMemOpDeclare.subst(McrDccimvacIop) + decoder_output += MiscRegRegImmOpConstructor.subst(McrDccimvacIop) + exec_output += Mcr15Execute.subst(McrDccimvacIop) + \ + Mcr15InitiateAcc.subst(McrDccimvacIop) + \ + Mcr15CompleteAcc.subst(McrDccimvacIop) + isbCode = ''' // If the barrier is due to a CP15 access check for hyp traps if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB, Hcr, Cpsr, Scr, |