X86: Implement the sysret instruction in long mode.
[gem5.git] / src / cpu / base.cc
index 6409255f637fbec1da59a1e71ba4f1a3f3195d9b..0ef206d901a8766b85a14d030c2433976c6c2994 100644 (file)
@@ -194,6 +194,8 @@ BaseCPU::BaseCPU(Params *p)
         }
     }
 #if FULL_SYSTEM
+    interrupts->setCPU(this);
+
     profileEvent = NULL;
     if (params()->profile)
         profileEvent = new ProfileEvent(this, params()->profile);
@@ -285,7 +287,17 @@ BaseCPU::registerThreadContexts()
     for (int i = 0; i < threadContexts.size(); ++i) {
         ThreadContext *tc = threadContexts[i];
 
-        tc->setContextId(system->registerThreadContext(tc));
+        /** This is so that contextId and cpuId match where there is a
+         * 1cpu:1context relationship.  Otherwise, the order of registration
+         * could affect the assignment and cpu 1 could have context id 3, for
+         * example.  We may even want to do something like this for SMT so that
+         * cpu 0 has the lowest thread contexts and cpu N has the highest, but
+         * I'll just do this for now
+         */
+        if (number_of_threads == 1)
+            tc->setContextId(system->registerThreadContext(tc, _cpuId));
+        else
+            tc->setContextId(system->registerThreadContext(tc));
 #if !FULL_SYSTEM
         tc->getProcessPtr()->assignThreadContext(tc->contextId());
 #endif
@@ -329,14 +341,20 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
         CpuEvent::replaceThreadContext(oldTC, newTC);
 
         assert(newTC->contextId() == oldTC->contextId());
+        assert(newTC->threadId() == oldTC->threadId());
         system->replaceThreadContext(newTC, newTC->contextId());
 
-        if (DTRACE(Context))
+        /* This code no longer works since the zero register (e.g.,
+         * r31 on Alpha) doesn't necessarily contain zero at this
+         * point.
+           if (DTRACE(Context))
             ThreadContext::compare(oldTC, newTC);
+        */
     }
 
 #if FULL_SYSTEM
     interrupts = oldCPU->interrupts;
+    interrupts->setCPU(this);
 
     for (int i = 0; i < threadContexts.size(); ++i)
         threadContexts[i]->profileClear();
@@ -378,24 +396,6 @@ BaseCPU::ProfileEvent::process()
     cpu->schedule(this, curTick + interval);
 }
 
-void
-BaseCPU::postInterrupt(int int_num, int index)
-{
-    interrupts->post(int_num, index);
-}
-
-void
-BaseCPU::clearInterrupt(int int_num, int index)
-{
-    interrupts->clear(int_num, index);
-}
-
-void
-BaseCPU::clearInterrupts()
-{
-    interrupts->clearAll();
-}
-
 void
 BaseCPU::serialize(std::ostream &os)
 {