cpu: remove unnecessary data ptr from O3 internal read() funcs
[gem5.git] / src / sim / pseudo_inst.cc
index 80737003c4e6de7e25cdd763d81c1f69651741aa..67c47ce778e338be516ecfe60af4a84f669d1a7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2010-2012, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
 #include "debug/PseudoInst.hh"
 #include "debug/Quiesce.hh"
 #include "debug/WorkItems.hh"
+#include "dev/net/dist_iface.hh"
 #include "params/BaseCPU.hh"
 #include "sim/full_system.hh"
+#include "sim/initparam_keys.hh"
 #include "sim/process.hh"
 #include "sim/pseudo_inst.hh"
 #include "sim/serialize.hh"
@@ -141,7 +143,7 @@ pseudoInst(ThreadContext *tc, uint8_t func, uint8_t subfunc)
         break;
 
       case 0x30: // initparam_func
-        return initParam(tc);
+        return initParam(tc, args[0], args[1]);
 
       case 0x31: // loadsymbol_func
         loadsymbol(tc);
@@ -280,7 +282,7 @@ quiesceNs(ThreadContext *tc, uint64_t ns)
 
     BaseCPU *cpu = tc->getCpuPtr();
 
-    if (!cpu->params()->do_quiesce || ns == 0)
+    if (!cpu->params()->do_quiesce)
         return;
 
     EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
@@ -306,7 +308,7 @@ quiesceCycles(ThreadContext *tc, uint64_t cycles)
 
     BaseCPU *cpu = tc->getCpuPtr();
 
-    if (!cpu->params()->do_quiesce || cycles == 0)
+    if (!cpu->params()->do_quiesce)
         return;
 
     EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
@@ -357,8 +359,10 @@ void
 m5exit(ThreadContext *tc, Tick delay)
 {
     DPRINTF(PseudoInst, "PseudoInst::m5exit(%i)\n", delay);
-    Tick when = curTick() + delay * SimClock::Int::ns;
-    exitSimLoop("m5_exit instruction encountered", 0, when, 0, true);
+    if (DistIface::readyToExit(delay)) {
+        Tick when = curTick() + delay * SimClock::Int::ns;
+        exitSimLoop("m5_exit instruction encountered", 0, when, 0, true);
+    }
 }
 
 void
@@ -440,15 +444,47 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
 }
 
 uint64_t
-initParam(ThreadContext *tc)
+initParam(ThreadContext *tc, uint64_t key_str1, uint64_t key_str2)
 {
-    DPRINTF(PseudoInst, "PseudoInst::initParam()\n");
+    DPRINTF(PseudoInst, "PseudoInst::initParam() key:%s%s\n", (char *)&key_str1,
+            (char *)&key_str2);
     if (!FullSystem) {
         panicFsOnlyPseudoInst("initParam");
         return 0;
     }
 
-    return tc->getCpuPtr()->system->init_param;
+    // The key parameter string is passed in via two 64-bit registers. We copy
+    // out the characters from the 64-bit integer variables here and concatenate
+    // them in the key_str character buffer
+    const int len = 2 * sizeof(uint64_t) + 1;
+    char key_str[len];
+    memset(key_str, '\0', len);
+    if (key_str1 == 0) {
+        assert(key_str2 == 0);
+    } else {
+        strncpy(key_str, (char *)&key_str1, sizeof(uint64_t));
+    }
+
+    if (strlen(key_str) == sizeof(uint64_t)) {
+        strncpy(key_str + sizeof(uint64_t), (char *)&key_str2,
+                sizeof(uint64_t));
+    } else {
+        assert(key_str2 == 0);
+    }
+
+    // Compare the key parameter with the known values to select the return
+    // value
+    uint64_t val;
+    if (strcmp(key_str, InitParamKey::DEFAULT) == 0) {
+        val = tc->getCpuPtr()->system->init_param;
+    } else if (strcmp(key_str, InitParamKey::DIST_RANK) == 0) {
+        val = DistIface::rankParam();
+    } else if (strcmp(key_str, InitParamKey::DIST_SIZE) == 0) {
+        val = DistIface::sizeParam();
+    } else {
+        panic("Unknown key for initparam pseudo instruction:\"%s\"", key_str);
+    }
+    return val;
 }
 
 
@@ -501,10 +537,11 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
     if (!tc->getCpuPtr()->params()->do_checkpoint_insts)
         return;
 
-    Tick when = curTick() + delay * SimClock::Int::ns;
-    Tick repeat = period * SimClock::Int::ns;
-
-    exitSimLoop("checkpoint", 0, when, repeat);
+    if (DistIface::readyToCkpt(delay, period)) {
+        Tick when = curTick() + delay * SimClock::Int::ns;
+        Tick repeat = period * SimClock::Int::ns;
+        exitSimLoop("checkpoint", 0, when, repeat);
+    }
 }
 
 uint64_t
@@ -565,13 +602,13 @@ writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
 
     if (offset == 0) {
         // create a new file (truncate)
-        os = simout.create(filename, true);
+        os = simout.create(filename, true, true);
     } else {
         // do not truncate file if offset is non-zero
         // (ios::in flag is required as well to keep the existing data
         //  intact, otherwise existing data will be zeroed out.)
         os = simout.openFile(simout.directory() + filename,
-                            ios::in | ios::out | ios::binary);
+                            ios::in | ios::out | ios::binary, true);
     }
     if (!os)
         panic("could not open file %s\n", filename);
@@ -616,13 +653,18 @@ void
 workbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
 {
     DPRINTF(PseudoInst, "PseudoInst::workbegin(%i, %i)\n", workid, threadid);
-    tc->getCpuPtr()->workItemBegin();
     System *sys = tc->getSystemPtr();
     const System::Params *params = sys->params();
-    sys->workItemBegin(threadid, workid);
 
-    DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid, 
+    if (params->exit_on_work_items) {
+        exitSimLoop("workbegin", static_cast<int>(workid));
+        return;
+    }
+
+    DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
             threadid);
+    tc->getCpuPtr()->workItemBegin();
+    sys->workItemBegin(threadid, workid);
 
     //
     // If specified, determine if this is the specific work item the user
@@ -674,12 +716,17 @@ void
 workend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
 {
     DPRINTF(PseudoInst, "PseudoInst::workend(%i, %i)\n", workid, threadid);
-    tc->getCpuPtr()->workItemEnd();
     System *sys = tc->getSystemPtr();
     const System::Params *params = sys->params();
-    sys->workItemEnd(threadid, workid);
+
+    if (params->exit_on_work_items) {
+        exitSimLoop("workend", static_cast<int>(workid));
+        return;
+    }
 
     DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid);
+    tc->getCpuPtr()->workItemEnd();
+    sys->workItemEnd(threadid, workid);
 
     //
     // If specified, determine if this is the specific work item the user