summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa/insts
diff options
context:
space:
mode:
authorNikos Nikoleris <nikos.nikoleris@arm.com>2017-02-07 11:35:10 +0000
committerNikos Nikoleris <nikos.nikoleris@arm.com>2017-12-05 11:47:01 +0000
commiteeb36e5b6e81c6b9ea6a0c3c97573e762e58ae05 (patch)
tree9ea079dc4bc5b04cfc4b84a32c06225670be69dd /src/arch/arm/isa/insts
parentb9edb351454c2601070fb9432f23fc3914eb33c1 (diff)
downloadgem5-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.isa100
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,