From 6f5b89a07c90ebaa7caf744927f977d78d366326 Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 2 Mar 2007 20:48:00 +0000 Subject: [PATCH] MIPS Userland TLS register emulation, by Daniel Jacobowitz. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2465 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/main.c | 1 + linux-user/mips/syscall_nr.h | 2 +- linux-user/syscall.c | 21 ++++++++++++++++++++- target-mips/cpu.h | 4 ++++ target-mips/op.c | 7 +++++++ target-mips/translate.c | 6 ++++++ 6 files changed, 39 insertions(+), 2 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 3eb573db69..3671384486 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 3593e65d05..e869bcdd66 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 76b36524a1..acd098d87c 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 21651beb0e..69335a0189 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 21795ad370..7c7ce3ba3e 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 5a77e906f1..a9f7b75c46 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); -- 2.11.0