Commit 6f5b89a07c90ebaa7caf744927f977d78d366326
1 parent
c05ac0cd
MIPS Userland TLS register emulation, by Daniel Jacobowitz.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2465 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
39 additions
and
2 deletions
linux-user/main.c
| @@ -1297,6 +1297,7 @@ static const uint8_t mips_syscall_args[] = { | @@ -1297,6 +1297,7 @@ static const uint8_t mips_syscall_args[] = { | ||
| 1297 | MIPS_SYS(sys_add_key , 5) | 1297 | MIPS_SYS(sys_add_key , 5) |
| 1298 | MIPS_SYS(sys_request_key , 4) | 1298 | MIPS_SYS(sys_request_key , 4) |
| 1299 | MIPS_SYS(sys_keyctl , 5) | 1299 | MIPS_SYS(sys_keyctl , 5) |
| 1300 | + MIPS_SYS(sys_set_thread_area, 1) | ||
| 1300 | }; | 1301 | }; |
| 1301 | 1302 | ||
| 1302 | #undef MIPS_SYS | 1303 | #undef MIPS_SYS |
linux-user/mips/syscall_nr.h
| @@ -285,4 +285,4 @@ | @@ -285,4 +285,4 @@ | ||
| 285 | #define TARGET_NR_add_key (TARGET_NR_Linux + 280) | 285 | #define TARGET_NR_add_key (TARGET_NR_Linux + 280) |
| 286 | #define TARGET_NR_request_key (TARGET_NR_Linux + 281) | 286 | #define TARGET_NR_request_key (TARGET_NR_Linux + 281) |
| 287 | #define TARGET_NR_keyctl (TARGET_NR_Linux + 282) | 287 | #define TARGET_NR_keyctl (TARGET_NR_Linux + 282) |
| 288 | - | 288 | +#define TARGET_NR_set_thread_area (TARGET_NR_Linux + 283) |
linux-user/syscall.c
| @@ -165,6 +165,9 @@ _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) | @@ -165,6 +165,9 @@ _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) | ||
| 165 | #ifdef __NR_exit_group | 165 | #ifdef __NR_exit_group |
| 166 | _syscall1(int,exit_group,int,error_code) | 166 | _syscall1(int,exit_group,int,error_code) |
| 167 | #endif | 167 | #endif |
| 168 | +#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) | ||
| 169 | +_syscall1(int,set_tid_address,int *,tidptr) | ||
| 170 | +#endif | ||
| 168 | 171 | ||
| 169 | extern int personality(int); | 172 | extern int personality(int); |
| 170 | extern int flock(int, int); | 173 | extern int flock(int, int); |
| @@ -3968,6 +3971,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | @@ -3968,6 +3971,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | ||
| 3968 | #endif | 3971 | #endif |
| 3969 | #ifdef TARGET_NR_set_thread_area | 3972 | #ifdef TARGET_NR_set_thread_area |
| 3970 | case TARGET_NR_set_thread_area: | 3973 | case TARGET_NR_set_thread_area: |
| 3974 | +#ifdef TARGET_MIPS | ||
| 3975 | + ((CPUMIPSState *) cpu_env)->tls_value = arg1; | ||
| 3976 | + ret = 0; | ||
| 3977 | + break; | ||
| 3978 | +#else | ||
| 3979 | + goto unimplemented_nowarn; | ||
| 3980 | +#endif | ||
| 3981 | +#endif | ||
| 3982 | +#ifdef TARGET_NR_get_thread_area | ||
| 3971 | case TARGET_NR_get_thread_area: | 3983 | case TARGET_NR_get_thread_area: |
| 3972 | goto unimplemented_nowarn; | 3984 | goto unimplemented_nowarn; |
| 3973 | #endif | 3985 | #endif |
| @@ -3975,10 +3987,17 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | @@ -3975,10 +3987,17 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | ||
| 3975 | case TARGET_NR_getdomainname: | 3987 | case TARGET_NR_getdomainname: |
| 3976 | goto unimplemented_nowarn; | 3988 | goto unimplemented_nowarn; |
| 3977 | #endif | 3989 | #endif |
| 3990 | + | ||
| 3991 | +#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) | ||
| 3992 | + case TARGET_NR_set_tid_address: | ||
| 3993 | + ret = get_errno(set_tid_address((int *) arg1)); | ||
| 3994 | + break; | ||
| 3995 | +#endif | ||
| 3996 | + | ||
| 3978 | default: | 3997 | default: |
| 3979 | unimplemented: | 3998 | unimplemented: |
| 3980 | gemu_log("qemu: Unsupported syscall: %d\n", num); | 3999 | gemu_log("qemu: Unsupported syscall: %d\n", num); |
| 3981 | -#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_getdomainname) | 4000 | +#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) |
| 3982 | unimplemented_nowarn: | 4001 | unimplemented_nowarn: |
| 3983 | #endif | 4002 | #endif |
| 3984 | ret = -ENOSYS; | 4003 | ret = -ENOSYS; |
target-mips/cpu.h
| @@ -268,6 +268,10 @@ struct CPUMIPSState { | @@ -268,6 +268,10 @@ struct CPUMIPSState { | ||
| 268 | int SYNCI_Step; /* Address step size for SYNCI */ | 268 | int SYNCI_Step; /* Address step size for SYNCI */ |
| 269 | int CCRes; /* Cycle count resolution/divisor */ | 269 | int CCRes; /* Cycle count resolution/divisor */ |
| 270 | 270 | ||
| 271 | +#if defined(CONFIG_USER_ONLY) | ||
| 272 | + target_ulong tls_value; | ||
| 273 | +#endif | ||
| 274 | + | ||
| 271 | CPU_COMMON | 275 | CPU_COMMON |
| 272 | 276 | ||
| 273 | int ram_size; | 277 | int ram_size; |
target-mips/op.c
| @@ -2021,6 +2021,13 @@ void op_tlbr (void) | @@ -2021,6 +2021,13 @@ void op_tlbr (void) | ||
| 2021 | #endif | 2021 | #endif |
| 2022 | 2022 | ||
| 2023 | /* Specials */ | 2023 | /* Specials */ |
| 2024 | +#if defined (CONFIG_USER_ONLY) | ||
| 2025 | +void op_tls_value (void) | ||
| 2026 | +{ | ||
| 2027 | + T0 = env->tls_value; | ||
| 2028 | +} | ||
| 2029 | +#endif | ||
| 2030 | + | ||
| 2024 | void op_pmon (void) | 2031 | void op_pmon (void) |
| 2025 | { | 2032 | { |
| 2026 | CALL_FROM_TB1(do_pmon, PARAM1); | 2033 | CALL_FROM_TB1(do_pmon, PARAM1); |
target-mips/translate.c
| @@ -4728,6 +4728,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4728,6 +4728,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
| 4728 | case 3: | 4728 | case 3: |
| 4729 | gen_op_rdhwr_ccres(); | 4729 | gen_op_rdhwr_ccres(); |
| 4730 | break; | 4730 | break; |
| 4731 | +#if defined (CONFIG_USER_ONLY) | ||
| 4732 | + case 29: | ||
| 4733 | + gen_op_tls_value (); | ||
| 4734 | + GEN_STORE_TN_REG(rt, T0); | ||
| 4735 | + break; | ||
| 4736 | +#endif | ||
| 4731 | default: /* Invalid */ | 4737 | default: /* Invalid */ |
| 4732 | MIPS_INVAL("rdhwr"); | 4738 | MIPS_INVAL("rdhwr"); |
| 4733 | generate_exception(ctx, EXCP_RI); | 4739 | generate_exception(ctx, EXCP_RI); |