ARM: Rework how unrecognized/unimplemented instructions are handled.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:04 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:04 +0000 (12:58 -0500)
Instead of panic immediately when these instructions are executed, an
UndefinedInstruction fault is returned. In FS mode (not currently
implemented), this is the fault that should, to my knowledge, be triggered in
these situations and should be handled using the normal architected
mechanisms. In SE mode, the fault causes a panic when it's invoked that gives
the same information as the instruction did. When/if support for speculative
execution of ARM is supported, this will allow a mispeculated and unrecognized
and/or unimplemented instruction from causing a panic. Only once the
instruction is going to be committed will the fault be invoked, triggering the
panic.

src/arch/arm/faults.cc
src/arch/arm/faults.hh
src/arch/arm/insts/static_inst.hh
src/arch/arm/isa/formats/unimp.isa
src/arch/arm/isa/formats/unknown.isa
src/arch/arm/utility.hh

index 2f939ea8c34f906093c29e846e462e47146933b7..9e32a23a391cc2f0f493e8c27e2b8177d8010372 100644 (file)
@@ -142,6 +142,24 @@ ArmFaultBase::invoke(ThreadContext *tc)
     tc->setPC(newPc);
     tc->setNextPC(newPc + cpsr.t ? 2 : 4 );
 }
+
+#else
+
+void
+UndefinedInstruction::invoke(ThreadContext *tc)
+{
+    assert(unknown || mnemonic != NULL);
+    if (unknown) {
+        panic("Attempted to execute unknown instruction "
+              "(inst 0x%08x, opcode 0x%x, binary:%s)",
+              machInst, machInst.opcode, inst2string(machInst));
+    } else {
+        panic("Attempted to execute unimplemented instruction '%s' "
+              "(inst 0x%08x, opcode 0x%x, binary:%s)",
+              mnemonic, machInst, machInst.opcode, inst2string(machInst));
+    }
+}
+
 #endif // FULL_SYSTEM
 
 // return via SUBS pc, lr, xxx; rfe, movs, ldm
index 7f8aa66b660f26adfb077d6f7af53407a9214a1c..90a730507beba4b9e4e83e95ea97584c252109f6 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2003-2005 The Regents of The University of Michigan
  * Copyright (c) 2007-2008 The Florida State University
  * All rights reserved.
@@ -92,7 +104,27 @@ class ArmFault : public ArmFaultBase
 
 
 class Reset                : public ArmFault<Reset> {};
-class UndefinedInstruction : public ArmFault<UndefinedInstruction> {};
+
+class UndefinedInstruction : public ArmFault<UndefinedInstruction>
+{
+#if !FULL_SYSTEM
+  protected:
+    ExtMachInst machInst;
+    bool unknown;
+    const char *mnemonic;
+
+  public:
+    UndefinedInstruction(ExtMachInst _machInst,
+                         bool _unknown,
+                         const char *_mnemonic = NULL) :
+        machInst(_machInst), unknown(_unknown), mnemonic(_mnemonic)
+    {
+    }
+
+    void invoke(ThreadContext *tc);
+#endif
+};
+
 class SupervisorCall       : public ArmFault<SupervisorCall> {};
 class PrefetchAbort        : public ArmFault<PrefetchAbort> {};
 class DataAbort            : public ArmFault<DataAbort> {};
index 35dbe6d521edaf176bd548d2051b83f2e06ea4e5..485d6997ed14648daa978a4b76d9eea0821d6761 100644 (file)
@@ -67,20 +67,6 @@ class ArmStaticInst : public StaticInst
     {
     }
 
-    inline static std::string
-    inst2string(MachInst machInst)
-    {
-        std::string str = "";
-        uint32_t mask = (1 << 31);
-
-        while (mask) {
-            str += ((machInst & mask) ? "1" : "0");
-            mask = mask >> 1;
-        }
-
-        return str;
-    }
-
     /// Print a register name for disassembly given the unique
     /// dependence tag number (FP or int).
     void printReg(std::ostream &os, int reg) const;
index e7bf67f68a2fee109b27df2eac0af7391114c0ec..a746f8a7b3f007b23aaec3cb0f7bb799cc013e18 100644 (file)
@@ -1,5 +1,17 @@
 // -*- mode:c++ -*-
 
+// Copyright (c) 2010 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
+//
 // Copyright (c) 2007-2008 The Florida State University
 // All rights reserved.
 //
@@ -112,10 +124,11 @@ output exec {{
     FailUnimplemented::execute(%(CPU_exec_context)s *xc,
                                Trace::InstRecord *traceData) const
     {
-        panic("attempt to execute unimplemented instruction '%s' "
-              "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
-              inst2string(machInst));
-        return new UnimpFault("Unimplemented Instruction");
+#if FULL_SYSTEM
+        return new UndefinedInstruction;
+#else
+        return new UndefinedInstruction(machInst, false, mnemonic);
+#endif
     }
 
     Fault
index 97a0caa6bbfe934667fcca69c4f79844d577b30b..e4bb948992e794e5c3e3f14ff45aa073083b544c 100644 (file)
@@ -1,5 +1,17 @@
 // -*- mode:c++ -*-
 
+// Copyright (c) 2010 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
+//
 // Copyright (c) 2007-2008 The Florida State University
 // All rights reserved.
 //
@@ -72,9 +84,11 @@ output exec {{
     Unknown::execute(%(CPU_exec_context)s *xc,
                      Trace::InstRecord *traceData) const
     {
-        panic("attempt to execute unknown instruction "
-              "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
-        return new UnimpFault("Unimplemented Instruction");
+#if FULL_SYSTEM
+        return new UndefinedInstruction;
+#else
+        return new UndefinedInstruction(machInst, true);
+#endif
     }
 }};
 
index 5739ba3cd03c96739797649ecf2b8093d8691c8f..b2c678c46a63cd7db9c6a63ab2d3cec720a6c788 100644 (file)
@@ -146,6 +146,20 @@ namespace ArmISA {
         return (tc->readMiscRegNoEffect(MISCREG_CPSR) & 0x1f) == MODE_USER;
     }
 
+    static inline std::string
+    inst2string(MachInst machInst)
+    {
+        std::string str = "";
+        uint32_t mask = (1 << 31);
+
+        while (mask) {
+            str += ((machInst & mask) ? "1" : "0");
+            mask = mask >> 1;
+        }
+
+        return str;
+    }
+
 uint64_t getArgument(ThreadContext *tc, int number, bool fp);
     
 Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);