From fe8faa62b74087febe227f69385db3e562682799 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 29 May 2018 16:30:33 +0100 Subject: [PATCH] arch-arm: Add Illegal Execution flag to PCState This patch moves the detection of the Illegal Execution flag (PSTATE.IL) from the tlb translation stage (fetch) to the decoding stage. This is done by adding the illegalExecution field to the PCState. Change-Id: I9c1c4e9c6bd5ded905c1d56b3034e4e9322582fa Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/10813 Maintainer: Andreas Sandberg --- src/arch/arm/decoder.cc | 4 +++- src/arch/arm/faults.cc | 2 ++ src/arch/arm/insts/pseudo.cc | 10 ++++++++++ src/arch/arm/insts/pseudo.hh | 15 +++++++++++++++ src/arch/arm/isa.cc | 1 + src/arch/arm/isa/bitfields.isa | 3 ++- src/arch/arm/isa/decoder/decoder.isa | 20 +++++++++++--------- src/arch/arm/isa/formats/pseudo.isa | 11 ++++++++++- src/arch/arm/tlb.cc | 5 ----- 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(); +} 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 @@ -53,6 +53,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(); - } - // 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,9 +239,21 @@ 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 { @@ -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); } }; -- 2.30.2