ARM: Add IsSerializeAfter and IsNonSpeculative flag to the syscall instruction .
[gem5.git] / src / arch / x86 / faults.cc
index 20b5a931e8bb6774f72e0360bc7b001fadd16a17..feb88fd763f1b539d0841a78c7285cfe6d9f94a0 100644 (file)
 #include "base/trace.hh"
 #include "config/full_system.hh"
 #include "cpu/thread_context.hh"
+
 #if !FULL_SYSTEM
 #include "arch/x86/isa_traits.hh"
 #include "mem/page_table.hh"
 #include "sim/process.hh"
 #else
 #include "arch/x86/tlb.hh"
+#include "debug/Faults.hh"
 #endif
 
 namespace X86ISA
 {
 #if FULL_SYSTEM
-    void X86FaultBase::invoke(ThreadContext * tc)
+    void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
     {
-        Addr pc = tc->readPC();
+        PCState pcState = tc->pcState();
+        Addr pc = pcState.pc();
         DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe());
         using namespace X86ISAInst::RomLabels;
         HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
@@ -86,8 +89,9 @@ namespace X86ISA
             assert(!isSoft());
             tc->setIntReg(INTREG_MICRO(15), errorCode);
         }
-        tc->setMicroPC(romMicroPC(entry));
-        tc->setNextMicroPC(romMicroPC(entry) + 1);
+        pcState.upc(romMicroPC(entry));
+        pcState.nupc(romMicroPC(entry) + 1);
+        tc->pcState(pcState);
     }
 
     std::string
@@ -102,21 +106,20 @@ namespace X86ISA
         return ss.str();
     }
     
-    void X86Trap::invoke(ThreadContext * tc)
+    void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
     {
         X86FaultBase::invoke(tc);
         // This is the same as a fault, but it happens -after- the instruction.
-        tc->setPC(tc->readNextPC());
-        tc->setNextPC(tc->readNextNPC());
-        tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
+        PCState pc = tc->pcState();
+        pc.uEnd();
     }
 
-    void X86Abort::invoke(ThreadContext * tc)
+    void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
     {
         panic("Abort exception!");
     }
 
-    void PageFault::invoke(ThreadContext * tc)
+    void PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
     {
         HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
         X86FaultBase::invoke(tc);
@@ -141,7 +144,7 @@ namespace X86ISA
     }
 
     void
-    InitInterrupt::invoke(ThreadContext *tc)
+    InitInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
     {
         DPRINTF(Faults, "Init interrupt.\n");
         // The otherwise unmodified integer registers should be set to 0.
@@ -207,9 +210,8 @@ namespace X86ISA
         tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
         tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);
 
-        tc->setPC(0x000000000000fff0ULL +
-                tc->readMiscReg(MISCREG_CS_BASE));
-        tc->setNextPC(tc->readPC() + sizeof(MachInst));
+        PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE));
+        tc->pcState(pc);
 
         tc->setMiscReg(MISCREG_TSG_BASE, 0);
         tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);
@@ -243,12 +245,13 @@ namespace X86ISA
         // Update the handy M5 Reg.
         tc->setMiscReg(MISCREG_M5_REG, 0);
         MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
-        tc->setMicroPC(romMicroPC(entry));
-        tc->setNextMicroPC(romMicroPC(entry) + 1);
+        pc.upc(romMicroPC(entry));
+        pc.nupc(romMicroPC(entry) + 1);
+        tc->pcState(pc);
     }
 
     void
-    StartupInterrupt::invoke(ThreadContext *tc)
+    StartupInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
     {
         DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
         HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
@@ -263,8 +266,30 @@ namespace X86ISA
         // This has the base value pre-added.
         tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);
 
-        tc->setPC(tc->readMiscReg(MISCREG_CS_BASE));
-        tc->setNextPC(tc->readPC() + sizeof(MachInst));
+        tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
+    }
+
+#else
+
+    void
+    InvalidOpcode::invoke(ThreadContext * tc, StaticInstPtr inst)
+    {
+        panic("Unrecognized/invalid instruction executed:\n %s",
+                inst->machInst);
+    }
+
+    void
+    PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
+    {
+        PageFaultErrorCode code = errorCode;
+        const char *modeStr = "";
+        if (code.fetch)
+            modeStr = "execute";
+        else if (code.write)
+            modeStr = "write";
+        else
+            modeStr = "read";
+        panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
     }
 
 #endif