ARM: Implement WFE/WFI/SEV semantics.
[gem5.git] / src / sim / syscall_emul.cc
index d25f7b9fa10444119be1b367cf3b0dd2c9abd79c..6873d4aa4cc80b2426987b128c1b055dd88b51c8 100644 (file)
 #include <fcntl.h>
 #include <unistd.h>
 
-#include <string>
+#include <cstdio>
 #include <iostream>
+#include <string>
 
-#include "sim/syscall_emul.hh"
+#include "arch/utility.hh"
 #include "base/chunk_generator.hh"
 #include "base/trace.hh"
 #include "config/the_isa.hh"
-#include "cpu/thread_context.hh"
 #include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+#include "debug/SyscallVerbose.hh"
 #include "mem/page_table.hh"
 #include "sim/process.hh"
-#include "sim/system.hh"
 #include "sim/sim_exit.hh"
+#include "sim/syscall_emul.hh"
+#include "sim/system.hh"
 
 using namespace std;
 using namespace TheISA;
@@ -52,10 +55,12 @@ using namespace TheISA;
 void
 SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
 {
+#if TRACING_ON
     int index = 0;
+#endif
     DPRINTFR(SyscallVerbose,
              "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n",
-             curTick, tc->getCpuPtr()->name(), name,
+             curTick(), tc->getCpuPtr()->name(), name,
              process->getSyscallArg(tc, index),
              process->getSyscallArg(tc, index),
              process->getSyscallArg(tc, index),
@@ -64,7 +69,7 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
     SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
 
     DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n",
-             curTick,tc->getCpuPtr()->name(), name, retval.value());
+             curTick(),tc->getCpuPtr()->name(), name, retval.value());
 
     if (!(flags & SyscallDesc::SuppressReturnValue))
         process->setSyscallReturn(tc, retval);
@@ -93,6 +98,18 @@ ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
 }
 
 
+SyscallReturn
+ignoreWarnOnceFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
+{
+    int index = 0;
+    warn_once("ignoring syscall %s(%d, %d, ...)", desc->name,
+         process->getSyscallArg(tc, index), process->getSyscallArg(tc, index));
+
+    return 0;
+}
+
+
 SyscallReturn
 exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
          ThreadContext *tc)
@@ -183,7 +200,10 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     int index = 0;
     int target_fd = p->getSyscallArg(tc, index);
-    int status = close(p->sim_fd(target_fd));
+    int sim_fd = p->sim_fd(target_fd);
+    int status = 0;
+    if (sim_fd > 2)
+        status = close(sim_fd);
     if (status >= 0)
         p->free_fd(target_fd);
     return status;
@@ -303,7 +323,7 @@ SyscallReturn
 getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     int result = 0;
-    int index;
+    int index = 0;
     Addr bufPtr = p->getSyscallArg(tc, index);
     unsigned long size = p->getSyscallArg(tc, index);
     BufferArg buf(bufPtr, size);
@@ -448,6 +468,29 @@ ftruncateFunc(SyscallDesc *desc, int num,
     return (result == -1) ? -errno : result;
 }
 
+SyscallReturn
+truncate64Func(SyscallDesc *desc, int num,
+                LiveProcess *process, ThreadContext *tc)
+{
+    int index = 0;
+    string path;
+
+    if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index)))
+       return -EFAULT;
+
+    int64_t length = process->getSyscallArg(tc, index, 64);
+
+    // Adjust path for current working directory
+    path = process->fullPath(path);
+
+#if NO_STAT64
+    int result = truncate(path.c_str(), length);
+#else
+    int result = truncate64(path.c_str(), length);
+#endif
+    return (result == -1) ? -errno : result;
+}
+
 SyscallReturn
 ftruncate64Func(SyscallDesc *desc, int num,
                 LiveProcess *process, ThreadContext *tc)
@@ -458,9 +501,13 @@ ftruncate64Func(SyscallDesc *desc, int num,
     if (fd < 0)
         return -EBADF;
 
-    loff_t length = process->getSyscallArg(tc, index, 64);
+    int64_t length = process->getSyscallArg(tc, index, 64);
 
+#if NO_STAT64
+    int result = ftruncate(fd, length);
+#else
     int result = ftruncate64(fd, length);
+#endif
     return (result == -1) ? -errno : result;
 }
 
@@ -768,6 +815,8 @@ cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
 
             for (int y = 8; y < 32; y++)
                 ctc->setIntReg(y, tc->readIntReg(y));
+        #elif THE_ISA == ARM_ISA
+            TheISA::copyRegs(tc, ctc);
         #else
             fatal("sys_clone is not implemented for this ISA\n");
         #endif
@@ -790,9 +839,7 @@ cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
             ctc->setIntReg(TheISA::SyscallPseudoReturnReg, 1);
         #endif
 
-        ctc->setPC(tc->readNextPC());
-        ctc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst));
-        ctc->setNextNPC(tc->readNextNPC() + sizeof(TheISA::MachInst));
+        ctc->pcState(tc->nextInstAddr());
 
         ctc->activate();