ARM: Add minimal ARM_SE support for m5threads.
authorChris Emmons <Chris.Emmons@ARM.com>
Fri, 18 Mar 2011 00:20:20 +0000 (19:20 -0500)
committerChris Emmons <Chris.Emmons@ARM.com>
Fri, 18 Mar 2011 00:20:20 +0000 (19:20 -0500)
Updated some of the assembly code sequences to use armv7 instructions and
coprocessor 15 for storing the TLS pointer.

src/arch/arm/linux/process.cc
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh

index e3455d21126c95f908ed8fbd97581563f32e207e..fc48ec12d0854210f0fea0a5c7a87812566b47c2 100644 (file)
@@ -197,7 +197,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
     /* 117 */ SyscallDesc("ipc", unimplementedFunc),
     /* 118 */ SyscallDesc("fsync", unimplementedFunc),
     /* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
-    /* 120 */ SyscallDesc("clone", unimplementedFunc),
+    /* 120 */ SyscallDesc("clone", cloneFunc),
     /* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
     /* 122 */ SyscallDesc("uname", unameFunc),
     /* 123 */ SyscallDesc("unused#123", unimplementedFunc),
@@ -239,7 +239,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
     /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
     /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
     /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
-    /* 162 */ SyscallDesc("nanosleep", unimplementedFunc),
+    /* 162 */ SyscallDesc("nanosleep", ignoreWarnOnceFunc),
     /* 163 */ SyscallDesc("mremap", mremapFunc<ArmLinux>), // ARM-specific
     /* 164 */ SyscallDesc("setresuid", unimplementedFunc),
     /* 165 */ SyscallDesc("getresuid", unimplementedFunc),
@@ -251,8 +251,8 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
     /* 171 */ SyscallDesc("getresgid", unimplementedFunc),
     /* 172 */ SyscallDesc("prctl", unimplementedFunc),
     /* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
-    /* 174 */ SyscallDesc("rt_sigaction", ignoreFunc),
-    /* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+    /* 174 */ SyscallDesc("rt_sigaction", ignoreWarnOnceFunc),
+    /* 175 */ SyscallDesc("rt_sigprocmask", ignoreWarnOnceFunc),
     /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc),
     /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
     /* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
@@ -317,7 +317,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
     /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc),
     /* 238 */ SyscallDesc("tkill", unimplementedFunc),
     /* 239 */ SyscallDesc("sendfile64", unimplementedFunc),
-    /* 240 */ SyscallDesc("futex", unimplementedFunc),
+    /* 240 */ SyscallDesc("futex", ignoreWarnOnceFunc),
     /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
     /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
     /* 243 */ SyscallDesc("io_setup", unimplementedFunc),
@@ -456,6 +456,7 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
 
     tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
                                 (uint8_t *)&tlsPtr, sizeof(tlsPtr));
+    tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
     return 0;
 }
 
@@ -508,7 +509,7 @@ ArmLinuxProcess::startup()
     ThreadContext *tc = system->getThreadContext(contextIds[0]);
 
     uint8_t swiNeg1[] = {
-        0xff, 0xff, 0xff, 0xef  //swi -1
+        0xff, 0xff, 0xff, 0xef  // swi -1
     };
 
     // Fill this page with swi -1 so we'll no if we land in it somewhere.
@@ -521,7 +522,8 @@ ArmLinuxProcess::startup()
     // @todo Add a barrrier in this code
     uint8_t memory_barrier[] =
     {
-        0x0e, 0xf0, 0xa0, 0xe1  //usr_ret lr
+        0x5f, 0xf0, 0x7f, 0xf5, // dmb
+        0x0e, 0xf0, 0xa0, 0xe1  // return
     };
     tc->getMemPort()->writeBlob(commPage + 0x0fa0, memory_barrier,
                                 sizeof(memory_barrier));
@@ -531,18 +533,22 @@ ArmLinuxProcess::startup()
     // @todo replace this with ldrex/strex and dmb
     uint8_t cmpxchg[] =
     {
-        0x00, 0x30, 0x92, 0xe5, //ldr r3, [r2]
-        0x00, 0x30, 0x53, 0xe0, //subs r3, r3, r0
-        0x00, 0x10, 0x82, 0x05, //streq r1, [r2]
-        0x03, 0x00, 0xa0, 0xe1, //mov r0, r3
-        0x0e, 0xf0, 0xa0, 0xe1  //usr_ret lr
+        0x9f, 0x3f, 0x92, 0xe1,  // ldrex    r3, [r2]
+        0x00, 0x30, 0x53, 0xe0,  // subs     r3, r3, r0
+        0x91, 0x3f, 0x82, 0x01,  // strexeq  r3, r1, [r2]
+        0x01, 0x00, 0x33, 0x03,  // teqeq    r3, #1
+        0xfa, 0xff, 0xff, 0x0a,  // beq 1b
+        0x00, 0x00, 0x73, 0xe2,  // rsbs r0, r3, #0
+        0x5f, 0xf0, 0x7f, 0xf5,  // dmb
+        0x0e, 0xf0, 0xa0, 0xe1   // return
     };
     tc->getMemPort()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
 
     uint8_t get_tls[] =
     {
-        0x08, 0x00, 0x9f, 0xe5, //ldr r0, [pc, #(16 - 8)]
-        0x0e, 0xf0, 0xa0, 0xe1  //usr_ret lr
+                                // read user read-only thread id register
+        0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
+        0x0e, 0xf0, 0xa0, 0xe1  // return
     };
     tc->getMemPort()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
 }
index e0469744e51e48f7a9568e36c84ceb2ffff772c4..506b22fdfa30a50d0a15078a5cb513a0fbfdd2fb 100644 (file)
@@ -97,6 +97,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)
@@ -802,6 +814,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
index 1dc51ad5686944d01ebe586e3fd0bff5ac55acbf..5091c275d4bac51a56c4e668905d3d58afd487c4 100644 (file)
@@ -187,6 +187,8 @@ SyscallReturn unimplementedFunc(SyscallDesc *desc, int num,
 /// trace flag is enabled.  Return success to the target program.
 SyscallReturn ignoreFunc(SyscallDesc *desc, int num,
                          LiveProcess *p, ThreadContext *tc);
+SyscallReturn ignoreWarnOnceFunc(SyscallDesc *desc, int num,
+                         LiveProcess *p, ThreadContext *tc);
 
 /// Target exit() handler: terminate current context.
 SyscallReturn exitFunc(SyscallDesc *desc, int num,