inorder: treat SE mode syscalls as a trapping instruction
authorKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:38 +0000 (21:43 -0400)
committerKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:38 +0000 (21:43 -0400)
define a syscallContext to schedule the syscall and then use syscall() to actually perform the action

src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/inorder/inorder_dyn_inst.hh
src/cpu/inorder/resources/execution_unit.cc

index 7ef48608aafac2b44a1eefb152091d86f0a1ba91..a634535bc1e5adc70045e619864abe8738c1e7d0 100644 (file)
@@ -105,7 +105,7 @@ std::string InOrderCPU::eventNames[NumCPUEvents] =
     "HaltThread",
     "SuspendThread",
     "Trap",
-    "InstGraduated",
+    "Syscall",
     "SquashFromMemStall",
     "UpdatePCs"
 };
@@ -151,6 +151,11 @@ InOrderCPU::CPUEvent::process()
         cpu->resPool->trap(fault, tid, inst);
         break;
 
+      case Syscall:
+        cpu->syscall(inst->syscallNum, tid);
+        cpu->resPool->trap(fault, tid, inst);
+        break;
+
       default:
         fatal("Unrecognized Event Type %s", eventNames[cpuEventType]);    
     }
@@ -1068,9 +1073,6 @@ InOrderCPU::activateNextReadyContext(int delay)
 {
     DPRINTF(InOrderCPU,"Activating next ready thread\n");
 
-    // NOTE: Add 5 to the event priority so that we always activate
-    // threads after we've finished deactivating, squashing,etc.
-    // other threads
     scheduleCpuEvent(ActivateNextReadyThread, NoFault, 0/*tid*/, dummyInst[0], 
                      delay, ActivateNextReadyThread_Pri);
 
@@ -1382,11 +1384,6 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
     // Check for instruction-count-based events.
     comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
 
-    // Broadcast to other resources an instruction
-    // has been completed
-    resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst, 
-                           0, 0, tid);
-
     // Finally, remove instruction from CPU
     removeInst(inst);
 }
@@ -1600,6 +1597,12 @@ InOrderCPU::wakeup()
 #endif
 
 #if !FULL_SYSTEM
+void
+InOrderCPU::syscallContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
+{
+    scheduleCpuEvent(Syscall, fault, tid, inst, delay, Syscall_Pri);
+}
+
 void
 InOrderCPU::syscall(int64_t callnum, ThreadID tid)
 {
index c8ac33a89240e73f65b8399fd352e104bf0d2546..a8703082892e3de30b4f640e2cfb5ebef191ee81 100644 (file)
@@ -182,7 +182,7 @@ class InOrderCPU : public BaseCPU
         HaltThread,
         SuspendThread,
         Trap,
-        InstGraduated,
+        Syscall,
         SquashFromMemStall,
         UpdatePCs,
         NumCPUEvents
@@ -192,6 +192,7 @@ class InOrderCPU : public BaseCPU
 
     enum CPUEventPri {
         InOrderCPU_Pri                 = Event::CPU_Tick_Pri,
+        Syscall_Pri                    = Event::CPU_Tick_Pri + 9,
         ActivateNextReadyThread_Pri    = Event::CPU_Tick_Pri + 10
     };
 
@@ -207,6 +208,7 @@ class InOrderCPU : public BaseCPU
         DynInstPtr inst;
         Fault fault;
         unsigned vpe;
+        short syscall_num;
         
       public:
         /** Constructs a CPU event. */
@@ -436,6 +438,13 @@ class InOrderCPU : public BaseCPU
 
     /** Check if this address is a valid data address. */
     bool validDataAddr(Addr addr) { return true; }
+#else
+    /** Schedule a syscall on the CPU */
+    void syscallContext(Fault fault, ThreadID tid, DynInstPtr inst,
+                        int delay = 0);
+
+    /** Executes a syscall.*/
+    void syscall(int64_t callnum, ThreadID tid);
 #endif
 
     /** Schedule a trap on the CPU */
@@ -650,9 +659,6 @@ class InOrderCPU : public BaseCPU
     Fault write(DynInstPtr inst, uint8_t *data, unsigned size,
                 Addr addr, unsigned flags, uint64_t *write_res = NULL);
 
-    /** Executes a syscall.*/
-    void syscall(int64_t callnum, ThreadID tid);
-
   public:
     /** Per-Thread List of all the instructions in flight. */
     std::list<DynInstPtr> instList[ThePipeline::MaxThreads];
index 1252ed6d1b767891810d324a8db85ded934c6952..ccde20da4477a872dd09ffa4ddfce9171e8dd246 100644 (file)
@@ -296,7 +296,8 @@ InOrderDynInst::simPalCheck(int palFunc)
 void
 InOrderDynInst::syscall(int64_t callnum)
 {
-    cpu->syscall(callnum, this->threadNumber);
+    syscallNum = callnum;
+    cpu->syscallContext(NoFault, this->threadNumber, this);
 }
 #endif
 
index b374e24a6facaa901f6c516bd6d0c6d745bd7a12..d14a7edfdccef02ac738405f61a9b9031ad2d84e 100644 (file)
@@ -385,6 +385,9 @@ class InOrderDynInst : public FastAlloc, public RefCounted
     bool isQuiesce() const { return staticInst->isQuiesce(); }
     bool isIprAccess() const { return staticInst->isIprAccess(); }
     bool isUnverifiable() const { return staticInst->isUnverifiable(); }
+    bool isSyscall() const
+    { return staticInst->isSyscall(); }
+
 
     /////////////////////////////////////////////
     //
@@ -509,6 +512,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted
     void trap(Fault fault);
     bool simPalCheck(int palFunc);
 #else
+    short syscallNum;
+
     /** Calls a syscall. */
     void syscall(int64_t callnum);
 #endif
index 6b89c8230bb92d982340ab11978211970a9eb7e0..77ab21b2137ccc47277550cb9f35da448b973c0c 100644 (file)
@@ -89,6 +89,8 @@ ExecutionUnit::execute(int slot_num)
     DynInstPtr inst = reqs[slot_num]->inst;
     Fault fault = NoFault;
     Tick cur_tick = curTick();
+    unsigned stage_num = exec_req->getStageNum();
+    ThreadID tid = inst->readTid();
 #if TRACING_ON
     InstSeqNum seq_num = inst->seqNum;
 #endif
@@ -149,13 +151,10 @@ ExecutionUnit::execute(int slot_num)
                         assert(inst->isControl());
 
                         // Set up Squash Generated By this Misprediction
-                        unsigned stage_num = exec_req->getStageNum();
-                        ThreadID tid = inst->readTid();
                         TheISA::PCState pc = inst->pcState();
                         TheISA::advancePC(pc, inst->staticInst);
                         inst->setPredTarg(pc);
                         inst->setSquashInfo(stage_num);
-
                         setupSquash(inst, stage_num, tid);
 
                         DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i] Squashing from "
@@ -210,6 +209,15 @@ ExecutionUnit::execute(int slot_num)
                             seq_num,
                             (inst->resultType(0) == InOrderDynInst::Float) ?
                             inst->readFloatResult(0) : inst->readIntResult(0));
+
+#if !FULL_SYSTEM
+                    // The Syscall might change the PC, so conservatively
+                    // squash everything behing it
+                    if (inst->isSyscall()) {
+                        inst->setSquashInfo(stage_num);
+                        setupSquash(inst, stage_num, tid);
+                    }
+#endif
                 } else {
                     DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: had a %s "
                             "fault.\n", inst->readTid(), seq_num, fault->name());