arch-arm: Add Illegal Execution flag to PCState
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Tue, 29 May 2018 15:30:33 +0000 (16:30 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 14 Jun 2018 13:45:49 +0000 (13:45 +0000)
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 <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/10813
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

src/arch/arm/decoder.cc
src/arch/arm/faults.cc
src/arch/arm/insts/pseudo.cc
src/arch/arm/insts/pseudo.hh
src/arch/arm/isa.cc
src/arch/arm/isa/bitfields.isa
src/arch/arm/isa/decoder/decoder.isa
src/arch/arm/isa/formats/pseudo.isa
src/arch/arm/tlb.cc
src/arch/arm/types.hh

index 1502b061ff54c680d3756820c991c1bcc0bac672..ce039b731d01033d7fa06d5bfe1fde80c173fcab 100644 (file)
@@ -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;
index 676559f61afe0ef8058b4a6c153a509af87d0e58..dd4f9581c1c6de492488e0de485e3760e7d8cff1 100644 (file)
@@ -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
index e2504d61e073746b65e980ac34c308aa585eb925..2e8c3f10d4df7dba81be5f3ef291a5525b094a82 100644 (file)
@@ -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>();
+}
index ececbbb86dac1c892c62ad6a752cc76aa9481f0f..9065c6281c8457798792f5da7823de9502a5ea36 100644 (file)
@@ -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
index aaf209e30a90019128d4197bfe20cdafaad0b515..9b17927e0ce18f79c0e13febf8ab7060e104c1eb 100644 (file)
@@ -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
index ba9a39efbda59951e7ecad533b301c5bedb3ea4d..ac6989a33525a10569b2328df3e29e61b112b2d8 100644 (file)
@@ -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;
index c352e087026aebcbe5bccb79130f3642a5903f88..1c9acbebcfad73b644ec3c7de6a6b36fde702ff4 100644 (file)
@@ -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
 //
 // 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"
     }
 }
index 30c2320e142bd1a7e1077c95afe1dc1dfb9deb2c..407b1c8d3d9516f5f27f13a07bfeb4409a983f81 100644 (file)
@@ -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
index d2153e779673123b4eeba071cd52147b83c9502a..79eef1b8d33c9dfda12fbcdcbb21d9e1afddd3a1 100644 (file)
@@ -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;
index 84887a1ca913b7aa065cf7f3b8715864aee3c23d..07cdfadc8027ca5f2868c861899fa61af09cd351 100644 (file)
@@ -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);
         }
     };