diff options
-rw-r--r-- | src/arch/arm/decoder.cc | 4 | ||||
-rw-r--r-- | src/arch/arm/faults.cc | 2 | ||||
-rw-r--r-- | src/arch/arm/insts/pseudo.cc | 10 | ||||
-rw-r--r-- | src/arch/arm/insts/pseudo.hh | 15 | ||||
-rw-r--r-- | src/arch/arm/isa.cc | 1 | ||||
-rw-r--r-- | src/arch/arm/isa/bitfields.isa | 3 | ||||
-rw-r--r-- | src/arch/arm/isa/decoder/decoder.isa | 20 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/pseudo.isa | 11 | ||||
-rw-r--r-- | src/arch/arm/tlb.cc | 5 | ||||
-rw-r--r-- | src/arch/arm/types.hh | 27 |
10 files changed, 77 insertions, 21 deletions
diff --git a/src/arch/arm/decoder.cc b/src/arch/arm/decoder.cc index 1502b061f..ce039b731 100644 --- a/src/arch/arm/decoder.cc +++ b/src/arch/arm/decoder.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 ARM Limited + * Copyright (c) 2012-2014,2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -179,6 +179,8 @@ Decoder::decode(ArmISA::PCState &pc) if (foundIt) pc.nextItstate(itBits); this_emi.itstate = pc.itstate(); + this_emi.illegalExecution = pc.illegalExec() ? 1 : 0; + pc.size(inst_size); emi = 0; diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 676559f61..dd4f9581c 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -601,6 +601,7 @@ ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) pc.nextJazelle(pc.jazelle()); pc.aarch64(!cpsr.width); pc.nextAArch64(!cpsr.width); + pc.illegalExec(false); tc->pcState(pc); } @@ -684,6 +685,7 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst) PCState pc(new_pc); pc.aarch64(!cpsr.width); pc.nextAArch64(!cpsr.width); + pc.illegalExec(false); tc->pcState(pc); // If we have a valid instruction then use it to annotate this fault with diff --git a/src/arch/arm/insts/pseudo.cc b/src/arch/arm/insts/pseudo.cc index e2504d61e..2e8c3f10d 100644 --- a/src/arch/arm/insts/pseudo.cc +++ b/src/arch/arm/insts/pseudo.cc @@ -249,3 +249,13 @@ McrMrcImplDefined::generateDisassembly(Addr pc, { return csprintf("%-10s (implementation defined)", mnemonic); } + +IllegalExecInst::IllegalExecInst(ExtMachInst _machInst) + : ArmStaticInst("Illegal Execution", _machInst, No_OpClass) +{} + +Fault +IllegalExecInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const +{ + return std::make_shared<IllegalInstSetStateFault>(); +} diff --git a/src/arch/arm/insts/pseudo.hh b/src/arch/arm/insts/pseudo.hh index ececbbb86..9065c6281 100644 --- a/src/arch/arm/insts/pseudo.hh +++ b/src/arch/arm/insts/pseudo.hh @@ -161,4 +161,19 @@ class McrMrcImplDefined : public McrMrcMiscInst }; +/** + * This class is modelling instructions which are not going to be + * executed since they are flagged as Illegal Execution Instructions + * (PSTATE.IL = 1 or CPSR.IL = 1). + * The sole purpose of this instruction is to generate an appropriate + * fault when executed. + */ +class IllegalExecInst : public ArmStaticInst +{ + public: + IllegalExecInst(ExtMachInst _machInst); + + Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const; +}; + #endif diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index aaf209e30..9b17927e0 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -704,6 +704,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) PCState pc = tc->pcState(); pc.nextThumb(cpsr.t); pc.nextJazelle(cpsr.j); + pc.illegalExec(cpsr.il == 1); // Follow slightly different semantics if a CheckerCPU object // is connected diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index ba9a39efb..ac6989a33 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010, 2011 ARM Limited +// Copyright (c) 2010, 2011, 2018 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -47,6 +47,7 @@ // Opcode fields def bitfield DECODERFAULT decoderFault; +def bitfield ILLEGALEXEC illegalExecution; def bitfield ENCODING encoding; def bitfield OPCODE opcode; diff --git a/src/arch/arm/isa/decoder/decoder.isa b/src/arch/arm/isa/decoder/decoder.isa index c352e0870..1c9acbebc 100644 --- a/src/arch/arm/isa/decoder/decoder.isa +++ b/src/arch/arm/isa/decoder/decoder.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010-2011 ARM Limited +// Copyright (c) 2010-2011,2018 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -40,15 +40,17 @@ // // Authors: Gabe Black -decode DECODERFAULT default DecoderFault::decoderFault() { - 0: decode THUMB default Unknown::unknown() { - 0: decode AARCH64 { - 0: - ##include "arm.isa" +decode ILLEGALEXEC default IllegalExec::illegalExec() { + 0: decode DECODERFAULT default DecoderFault::decoderFault() { + 0: decode THUMB default Unknown::unknown() { + 0: decode AARCH64 { + 0: + ##include "arm.isa" + 1: + ##include "aarch64.isa" + } 1: - ##include "aarch64.isa" + ##include "thumb.isa" } - 1: - ##include "thumb.isa" } } diff --git a/src/arch/arm/isa/formats/pseudo.isa b/src/arch/arm/isa/formats/pseudo.isa index 30c2320e1..407b1c8d3 100644 --- a/src/arch/arm/isa/formats/pseudo.isa +++ b/src/arch/arm/isa/formats/pseudo.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2014 ARM Limited +// Copyright (c) 2014, 2018 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -55,6 +55,15 @@ def format DecoderFault() {{ //////////////////////////////////////////////////////////////////// // +// Illegal execution handling +// + +def format IllegalExec() {{ + decode_block = 'return new IllegalExecInst(machInst);\n' +}}; + +//////////////////////////////////////////////////////////////////// +// // Unknown instruction handling // diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index d2153e779..79eef1b8d 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -1145,11 +1145,6 @@ TLB::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode, } if (fault == NoFault) { - // Generate Illegal Inst Set State fault if IL bit is set in CPSR - if (aarch64 && is_fetch && cpsr.il == 1) { - return std::make_shared<IllegalInstSetStateFault>(); - } - // Don't try to finalize a physical address unless the // translation has completed (i.e., there is a table entry). return te ? finalizePhysical(req, tc, mode) : NoFault; diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 84887a1ca..07cdfadc8 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2013, 2017 ARM Limited + * Copyright (c) 2010, 2012-2013, 2017-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -70,6 +70,7 @@ namespace ArmISA BitUnion64(ExtMachInst) // Decoder state Bitfield<63, 62> decoderFault; // See DecoderFault + Bitfield<61> illegalExecution; // ITSTATE bits Bitfield<55, 48> itstate; @@ -218,14 +219,16 @@ namespace ArmISA JazelleBit = (1 << 1), AArch64Bit = (1 << 2) }; + uint8_t flags; uint8_t nextFlags; uint8_t _itstate; uint8_t _nextItstate; uint8_t _size; + bool _illegalExec; public: PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0), - _size(0) + _size(0), _illegalExec(false) {} void @@ -236,10 +239,22 @@ namespace ArmISA } PCState(Addr val) : flags(0), nextFlags(0), _itstate(0), - _nextItstate(0), _size(0) + _nextItstate(0), _size(0), _illegalExec(false) { set(val); } bool + illegalExec() const + { + return _illegalExec; + } + + void + illegalExec(bool val) + { + _illegalExec = val; + } + + bool thumb() const { return flags & ThumbBit; @@ -472,7 +487,9 @@ namespace ArmISA { return Base::operator == (opc) && flags == opc.flags && nextFlags == opc.nextFlags && - _itstate == opc._itstate && _nextItstate == opc._nextItstate; + _itstate == opc._itstate && + _nextItstate == opc._nextItstate && + _illegalExec == opc._illegalExec; } bool @@ -490,6 +507,7 @@ namespace ArmISA SERIALIZE_SCALAR(nextFlags); SERIALIZE_SCALAR(_itstate); SERIALIZE_SCALAR(_nextItstate); + SERIALIZE_SCALAR(_illegalExec); } void @@ -501,6 +519,7 @@ namespace ArmISA UNSERIALIZE_SCALAR(nextFlags); UNSERIALIZE_SCALAR(_itstate); UNSERIALIZE_SCALAR(_nextItstate); + UNSERIALIZE_SCALAR(_illegalExec); } }; |