summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-03-02 20:48:00 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-03-02 20:48:00 +0000
commit6f5b89a07c90ebaa7caf744927f977d78d366326 (patch)
treebea887cff59c2d381131d70d3057bb14e882ed6e
parentc05ac0cdac0c4592876424f9c467484bb1eb2bb6 (diff)
downloadhqemu-6f5b89a07c90ebaa7caf744927f977d78d366326.zip
hqemu-6f5b89a07c90ebaa7caf744927f977d78d366326.tar.gz
MIPS Userland TLS register emulation, by Daniel Jacobowitz.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2465 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--linux-user/main.c1
-rw-r--r--linux-user/mips/syscall_nr.h2
-rw-r--r--linux-user/syscall.c21
-rw-r--r--target-mips/cpu.h4
-rw-r--r--target-mips/op.c7
-rw-r--r--target-mips/translate.c6
6 files changed, 39 insertions, 2 deletions
diff --git a/linux-user/main.c b/linux-user/main.c
index 3eb573d..3671384 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1297,6 +1297,7 @@ static const uint8_t mips_syscall_args[] = {
MIPS_SYS(sys_add_key , 5)
MIPS_SYS(sys_request_key , 4)
MIPS_SYS(sys_keyctl , 5)
+ MIPS_SYS(sys_set_thread_area, 1)
};
#undef MIPS_SYS
diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h
index 3593e65..e869bcd 100644
--- a/linux-user/mips/syscall_nr.h
+++ b/linux-user/mips/syscall_nr.h
@@ -285,4 +285,4 @@
#define TARGET_NR_add_key (TARGET_NR_Linux + 280)
#define TARGET_NR_request_key (TARGET_NR_Linux + 281)
#define TARGET_NR_keyctl (TARGET_NR_Linux + 282)
-
+#define TARGET_NR_set_thread_area (TARGET_NR_Linux + 283)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 76b3652..acd098d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -165,6 +165,9 @@ _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
+#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
+_syscall1(int,set_tid_address,int *,tidptr)
+#endif
extern int personality(int);
extern int flock(int, int);
@@ -3968,6 +3971,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
#endif
#ifdef TARGET_NR_set_thread_area
case TARGET_NR_set_thread_area:
+#ifdef TARGET_MIPS
+ ((CPUMIPSState *) cpu_env)->tls_value = arg1;
+ ret = 0;
+ break;
+#else
+ goto unimplemented_nowarn;
+#endif
+#endif
+#ifdef TARGET_NR_get_thread_area
case TARGET_NR_get_thread_area:
goto unimplemented_nowarn;
#endif
@@ -3975,10 +3987,17 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
case TARGET_NR_getdomainname:
goto unimplemented_nowarn;
#endif
+
+#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
+ case TARGET_NR_set_tid_address:
+ ret = get_errno(set_tid_address((int *) arg1));
+ break;
+#endif
+
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);
-#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_getdomainname)
+#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname)
unimplemented_nowarn:
#endif
ret = -ENOSYS;
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 21651be..69335a0 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -268,6 +268,10 @@ struct CPUMIPSState {
int SYNCI_Step; /* Address step size for SYNCI */
int CCRes; /* Cycle count resolution/divisor */
+#if defined(CONFIG_USER_ONLY)
+ target_ulong tls_value;
+#endif
+
CPU_COMMON
int ram_size;
diff --git a/target-mips/op.c b/target-mips/op.c
index 21795ad..7c7ce3b 100644
--- a/target-mips/op.c
+++ b/target-mips/op.c
@@ -2021,6 +2021,13 @@ void op_tlbr (void)
#endif
/* Specials */
+#if defined (CONFIG_USER_ONLY)
+void op_tls_value (void)
+{
+ T0 = env->tls_value;
+}
+#endif
+
void op_pmon (void)
{
CALL_FROM_TB1(do_pmon, PARAM1);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 5a77e90..a9f7b75 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -4728,6 +4728,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
case 3:
gen_op_rdhwr_ccres();
break;
+#if defined (CONFIG_USER_ONLY)
+ case 29:
+ gen_op_tls_value ();
+ GEN_STORE_TN_REG(rt, T0);
+ break;
+#endif
default: /* Invalid */
MIPS_INVAL("rdhwr");
generate_exception(ctx, EXCP_RI);
OpenPOWER on IntegriCloud