diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2013-07-10 10:54:16 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-07-10 10:54:16 -0500 |
commit | 51455c59ddc370612f6e070d8eb0e594aaa7ef24 (patch) | |
tree | a3044bd466cb3a548e6abad273663469bf68647a /linux-user | |
parent | 9f9a03b9818194da39c6759d9b0cbee5d7ace4e1 (diff) | |
parent | 91b1df8cf9e1ecaa8679c9ea8713d1e25c28e6c4 (diff) |
Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
QOM CPUState refactorings
* Fix for OpenRISCCPU subclasses
* Fix for gdbstub CPU selection
* Move linux-user CPU functions into new header
* CPUState part 10 refactoring: first_cpu, next_cpu, cpu_single_env et al.
* Fix some targets to consistently inline TCG code generation
* Centrally log CPU reset
# gpg: Signature made Wed 10 Jul 2013 07:52:39 AM CDT using RSA key ID 3E7E013F
# gpg: Can't check signature: public key not found
# By Andreas Färber (41) and others
# Via Andreas Färber
* afaerber/tags/qom-cpu-for-anthony: (43 commits)
cpu: Move reset logging to CPUState
target-ppc: Change LOG_MMU_STATE() argument to CPUState
target-i386: Change LOG_PCALL_STATE() argument to CPUState
log: Change log_cpu_state[_mask]() argument to CPUState
target-i386: Change do_smm_enter() argument to X86CPU
target-i386: Change do_interrupt_all() argument to X86CPU
target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
target-unicore32: Change gen_intermediate_code_internal() signature
target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU
target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU
target-s390x: Change gen_intermediate_code_internal() argument to S390CPU
target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU
target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU
target-microblaze: Change gen_intermediate_code_internal() argument types
target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU
target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU
target-i386: Change gen_intermediate_code_internal() argument to X86CPU
target-cris: Change gen_intermediate_code_internal() argument to CRISCPU
target-arm: Change gen_intermediate_code_internal() argument to ARMCPU
target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU
...
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/alpha/target_cpu.h | 36 | ||||
-rw-r--r-- | linux-user/arm/target_cpu.h | 35 | ||||
-rw-r--r-- | linux-user/cris/target_cpu.h | 36 | ||||
-rw-r--r-- | linux-user/elfload.c | 21 | ||||
-rw-r--r-- | linux-user/i386/target_cpu.h | 33 | ||||
-rw-r--r-- | linux-user/linuxload.c | 3 | ||||
-rw-r--r-- | linux-user/m68k/target_cpu.h | 34 | ||||
-rw-r--r-- | linux-user/main.c | 21 | ||||
-rw-r--r-- | linux-user/microblaze/target_cpu.h | 35 | ||||
-rw-r--r-- | linux-user/mips/target_cpu.h | 36 | ||||
-rw-r--r-- | linux-user/mips64/target_cpu.h | 1 | ||||
-rw-r--r-- | linux-user/openrisc/target_cpu.h | 33 | ||||
-rw-r--r-- | linux-user/ppc/target_cpu.h | 41 | ||||
-rw-r--r-- | linux-user/qemu.h | 3 | ||||
-rw-r--r-- | linux-user/s390x/target_cpu.h | 39 | ||||
-rw-r--r-- | linux-user/sh4/target_cpu.h | 35 | ||||
-rw-r--r-- | linux-user/signal.c | 12 | ||||
-rw-r--r-- | linux-user/sparc/target_cpu.h | 36 | ||||
-rw-r--r-- | linux-user/sparc64/target_cpu.h | 1 | ||||
-rw-r--r-- | linux-user/syscall.c | 80 | ||||
-rw-r--r-- | linux-user/unicore32/target_cpu.h | 27 | ||||
-rw-r--r-- | linux-user/x86_64/target_cpu.h | 1 |
22 files changed, 534 insertions, 65 deletions
diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h new file mode 100644 index 0000000000..42562452b2 --- /dev/null +++ b/linux-user/alpha/target_cpu.h @@ -0,0 +1,36 @@ +/* + * Alpha specific CPU ABI and functions for linux-user + * + * Copyright (c) 2007 Jocelyn Mayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUAlphaState *env, target_ulong newsp) +{ + if (newsp) { + env->ir[IR_SP] = newsp; + } + env->ir[IR_V0] = 0; + env->ir[IR_A3] = 0; +} + +static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls) +{ + env->unique = newtls; +} + +#endif diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h new file mode 100644 index 0000000000..ed323c079d --- /dev/null +++ b/linux-user/arm/target_cpu.h @@ -0,0 +1,35 @@ +/* + * ARM specific CPU ABI and functions for linux-user + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) +{ + if (newsp) { + env->regs[13] = newsp; + } + env->regs[0] = 0; +} + +static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls) +{ + env->cp15.c13_tls2 = newtls; +} + +#endif diff --git a/linux-user/cris/target_cpu.h b/linux-user/cris/target_cpu.h new file mode 100644 index 0000000000..4d787e5ff3 --- /dev/null +++ b/linux-user/cris/target_cpu.h @@ -0,0 +1,36 @@ +/* + * CRIS specific CPU ABI and functions for linux-user + * + * Copyright (c) 2007 AXIS Communications AB + * Written by Edgar E. Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUCRISState *env, target_ulong newsp) +{ + if (newsp) { + env->regs[14] = newsp; + } + env->regs[10] = 0; +} + +static inline void cpu_set_tls(CPUCRISState *env, target_ulong newtls) +{ + env->pregs[PR_PID] = (env->pregs[PR_PID] & 0xff) | newtls; +} + +#endif diff --git a/linux-user/elfload.c b/linux-user/elfload.c index ddef23e6dc..7ce2eab1bb 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -125,7 +125,7 @@ typedef abi_int target_pid_t; static const char *get_elf_platform(void) { static char elf_platform[] = "i386"; - int family = (thread_env->cpuid_version >> 8) & 0xff; + int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL); if (family > 6) family = 6; if (family >= 3) @@ -137,7 +137,9 @@ static const char *get_elf_platform(void) static uint32_t get_elf_hwcap(void) { - return thread_env->features[FEAT_1_EDX]; + X86CPU *cpu = X86_CPU(thread_cpu); + + return cpu->env.features[FEAT_1_EDX]; } #ifdef TARGET_X86_64 @@ -404,7 +406,7 @@ static int validate_guest_space(unsigned long guest_base, static uint32_t get_elf_hwcap(void) { - CPUARMState *e = thread_env; + ARMCPU *cpu = ARM_CPU(thread_cpu); uint32_t hwcaps = 0; hwcaps |= ARM_HWCAP_ARM_SWP; @@ -415,7 +417,7 @@ static uint32_t get_elf_hwcap(void) /* probe for the extra features */ #define GET_FEATURE(feat, hwcap) \ - do {if (arm_feature(e, feat)) { hwcaps |= hwcap; } } while (0) + do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0) GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP); GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT); GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE); @@ -619,13 +621,13 @@ enum { static uint32_t get_elf_hwcap(void) { - CPUPPCState *e = thread_env; + PowerPCCPU *cpu = POWERPC_CPU(thread_cpu); uint32_t features = 0; /* We don't have to be terribly complete here; the high points are Altivec/FP/SPE support. Anything else is just a bonus. */ #define GET_FEATURE(flag, feature) \ - do {if (e->insns_flags & flag) features |= feature; } while(0) + do { if (cpu->env.insns_flags & flag) { features |= feature; } } while (0) GET_FEATURE(PPC_64B, QEMU_PPC_FEATURE_64); GET_FEATURE(PPC_FLOAT, QEMU_PPC_FEATURE_HAS_FPU); GET_FEATURE(PPC_ALTIVEC, QEMU_PPC_FEATURE_HAS_ALTIVEC); @@ -2628,7 +2630,7 @@ static int fill_note_info(struct elf_note_info *info, long signr, const CPUArchState *env) { #define NUMNOTES 3 - CPUArchState *cpu = NULL; + CPUState *cpu = NULL; TaskState *ts = (TaskState *)env->opaque; int i; @@ -2667,9 +2669,10 @@ static int fill_note_info(struct elf_note_info *info, /* read and fill status of all threads */ cpu_list_lock(); for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { - if (cpu == thread_env) + if (cpu == thread_cpu) { continue; - fill_thread_info(info, cpu); + } + fill_thread_info(info, (CPUArchState *)cpu->env_ptr); } cpu_list_unlock(); diff --git a/linux-user/i386/target_cpu.h b/linux-user/i386/target_cpu.h new file mode 100644 index 0000000000..abcac79d25 --- /dev/null +++ b/linux-user/i386/target_cpu.h @@ -0,0 +1,33 @@ +/* + * i386 specific CPU ABI and functions for linux-user + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp) +{ + if (newsp) { + env->regs[R_ESP] = newsp; + } + env->regs[R_EAX] = 0; +} + +/* TODO: need to implement cpu_set_tls() */ + +#endif diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index 381ab8914b..5cd6d91554 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -89,7 +89,8 @@ static int prepare_binprm(struct linux_binprm *bprm) abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, abi_ulong stringp, int push_ptr) { - TaskState *ts = (TaskState *)thread_env->opaque; + CPUArchState *env = thread_cpu->env_ptr; + TaskState *ts = (TaskState *)env->opaque; int n = sizeof(abi_ulong); abi_ulong envp; abi_ulong argv; diff --git a/linux-user/m68k/target_cpu.h b/linux-user/m68k/target_cpu.h new file mode 100644 index 0000000000..8a2a305a0b --- /dev/null +++ b/linux-user/m68k/target_cpu.h @@ -0,0 +1,34 @@ +/* + * m68k specific CPU ABI and functions for linux-user + * + * Copyright (c) 2005-2007 CodeSourcery + * Written by Paul Brook + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp) +{ + if (newsp) { + env->aregs[7] = newsp; + } + env->dregs[0] = 0; +} + +/* TODO: need to implement cpu_set_tls() */ + +#endif diff --git a/linux-user/main.c b/linux-user/main.c index af82db87b8..7f15d3da2b 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -120,15 +120,15 @@ void fork_end(int child) if (child) { /* Child processes created by fork() only have a single thread. Discard information about the parent threads. */ - first_cpu = thread_env; - thread_env->next_cpu = NULL; + first_cpu = thread_cpu; + first_cpu->next_cpu = NULL; pending_cpus = 0; pthread_mutex_init(&exclusive_lock, NULL); pthread_mutex_init(&cpu_list_mutex, NULL); pthread_cond_init(&exclusive_cond, NULL); pthread_cond_init(&exclusive_resume, NULL); pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL); - gdbserver_fork(thread_env); + gdbserver_fork((CPUArchState *)thread_cpu->env_ptr); } else { pthread_mutex_unlock(&exclusive_lock); pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock); @@ -148,7 +148,6 @@ static inline void exclusive_idle(void) Must only be called from outside cpu_arm_exec. */ static inline void start_exclusive(void) { - CPUArchState *other; CPUState *other_cpu; pthread_mutex_lock(&exclusive_lock); @@ -156,8 +155,7 @@ static inline void start_exclusive(void) pending_cpus = 1; /* Make all other cpus stop executing. */ - for (other = first_cpu; other; other = other->next_cpu) { - other_cpu = ENV_GET_CPU(other); + for (other_cpu = first_cpu; other_cpu; other_cpu = other_cpu->next_cpu) { if (other_cpu->running) { pending_cpus++; cpu_exit(other_cpu); @@ -234,7 +232,7 @@ void fork_start(void) void fork_end(int child) { if (child) { - gdbserver_fork(thread_env); + gdbserver_fork((CPUArchState *)thread_cpu->env_ptr); } } @@ -1304,11 +1302,12 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val) #define EXCP_DUMP(env, fmt, ...) \ do { \ + CPUState *cs = ENV_GET_CPU(env); \ fprintf(stderr, fmt , ## __VA_ARGS__); \ - cpu_dump_state(ENV_GET_CPU(env), stderr, fprintf, 0); \ + cpu_dump_state(cs, stderr, fprintf, 0); \ qemu_log(fmt, ## __VA_ARGS__); \ if (qemu_log_enabled()) { \ - log_cpu_state(env, 0); \ + log_cpu_state(cs, 0); \ } \ } while (0) @@ -3152,7 +3151,7 @@ void cpu_loop(CPUS390XState *env) #endif /* TARGET_S390X */ -THREAD CPUArchState *thread_env; +THREAD CPUState *thread_cpu; void task_settid(TaskState *ts) { @@ -3642,7 +3641,7 @@ int main(int argc, char **argv, char **envp) cpu_reset(ENV_GET_CPU(env)); #endif - thread_env = env; + thread_cpu = ENV_GET_CPU(env); if (getenv("QEMU_STRACE")) { do_strace = 1; diff --git a/linux-user/microblaze/target_cpu.h b/linux-user/microblaze/target_cpu.h new file mode 100644 index 0000000000..c6386ea9e4 --- /dev/null +++ b/linux-user/microblaze/target_cpu.h @@ -0,0 +1,35 @@ +/* + * MicroBlaze specific CPU ABI and functions for linux-user + * + * Copyright (c) 2009 Edgar E. Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUMBState *env, target_ulong newsp) +{ + if (newsp) { + env->regs[R_SP] = newsp; + } + env->regs[3] = 0; +} + +static inline void cpu_set_tls(CPUMBState *env, target_ulong newtls) +{ + env->regs[21] = newtls; +} + +#endif diff --git a/linux-user/mips/target_cpu.h b/linux-user/mips/target_cpu.h new file mode 100644 index 0000000000..ba8e9eb1f9 --- /dev/null +++ b/linux-user/mips/target_cpu.h @@ -0,0 +1,36 @@ +/* + * MIPS specific CPU ABI and functions for linux-user + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp) +{ + if (newsp) { + env->active_tc.gpr[29] = newsp; + } + env->active_tc.gpr[7] = 0; + env->active_tc.gpr[2] = 0; +} + +static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls) +{ + env->tls_value = newtls; +} + +#endif diff --git a/linux-user/mips64/target_cpu.h b/linux-user/mips64/target_cpu.h new file mode 100644 index 0000000000..fa36407c68 --- /dev/null +++ b/linux-user/mips64/target_cpu.h @@ -0,0 +1 @@ +#include "../mips/target_cpu.h" diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h new file mode 100644 index 0000000000..501fb81162 --- /dev/null +++ b/linux-user/openrisc/target_cpu.h @@ -0,0 +1,33 @@ +/* + * OpenRISC specific CPU ABI and functions for linux-user + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp) +{ + if (newsp) { + env->gpr[1] = newsp; + } + env->gpr[2] = 0; +} + +/* TODO: need to implement cpu_set_tls() */ + +#endif diff --git a/linux-user/ppc/target_cpu.h b/linux-user/ppc/target_cpu.h new file mode 100644 index 0000000000..9cc0c3ba9c --- /dev/null +++ b/linux-user/ppc/target_cpu.h @@ -0,0 +1,41 @@ +/* + * PowerPC specific CPU ABI and functions for linux-user + * + * Copyright (c) 2003-2007 Jocelyn Mayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp) +{ + if (newsp) { + env->gpr[1] = newsp; + } + env->gpr[3] = 0; +} + +static inline void cpu_set_tls(CPUPPCState *env, target_ulong newtls) +{ +#if defined(TARGET_PPC64) + /* The kernel checks TIF_32BIT here; we don't support loading 32-bit + binaries on PPC64 yet. */ + env->gpr[13] = newtls; +#else + env->gpr[2] = newtls; +#endif +} + +#endif diff --git a/linux-user/qemu.h b/linux-user/qemu.h index b10e9572a9..6569608b64 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -16,6 +16,7 @@ #include "exec/user/thunk.h" #include "syscall_defs.h" #include "syscall.h" +#include "target_cpu.h" #include "target_signal.h" #include "exec/gdbstub.h" #include "qemu/queue.h" @@ -197,7 +198,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg5, abi_long arg6, abi_long arg7, abi_long arg8); void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -extern THREAD CPUArchState *thread_env; +extern THREAD CPUState *thread_cpu; void cpu_loop(CPUArchState *env); char *target_strerror(int err); int get_osversion(void); diff --git a/linux-user/s390x/target_cpu.h b/linux-user/s390x/target_cpu.h new file mode 100644 index 0000000000..f10abe8e54 --- /dev/null +++ b/linux-user/s390x/target_cpu.h @@ -0,0 +1,39 @@ +/* + * S/390 specific CPU ABI and functions for linux-user + * + * Copyright (c) 2009 Ulrich Hecht + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Contributions after 2012-10-29 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + * + * You should have received a copy of the GNU (Lesser) General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp) +{ + if (newsp) { + env->regs[15] = newsp; + } + env->regs[2] = 0; +} + +static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls) +{ + env->aregs[0] = newtls >> 32; + env->aregs[1] = newtls & 0xffffffffULL; +} + +#endif diff --git a/linux-user/sh4/target_cpu.h b/linux-user/sh4/target_cpu.h new file mode 100644 index 0000000000..141856f845 --- /dev/null +++ b/linux-user/sh4/target_cpu.h @@ -0,0 +1,35 @@ +/* + * SH4 specific CPU ABI and functions for linux-user + * + * Copyright (c) 2005 Samuel Tardieu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUSH4State *env, target_ulong newsp) +{ + if (newsp) { + env->gregs[15] = newsp; + } + env->gregs[0] = 0; +} + +static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls) +{ + env->gbr = newtls; +} + +#endif diff --git a/linux-user/signal.c b/linux-user/signal.c index d84e189bc8..d0727becc2 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -388,17 +388,18 @@ static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q) /* abort execution with signal */ static void QEMU_NORETURN force_sig(int target_sig) { - TaskState *ts = (TaskState *)thread_env->opaque; + CPUArchState *env = thread_cpu->env_ptr; + TaskState *ts = (TaskState *)env->opaque; int host_sig, core_dumped = 0; struct sigaction act; host_sig = target_to_host_signal(target_sig); - gdb_signalled(thread_env, target_sig); + gdb_signalled(env, target_sig); /* dump core if supported by target binary format */ if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) { stop_all_tasks(); core_dumped = - ((*ts->bprm->core_dump)(target_sig, thread_env) == 0); + ((*ts->bprm->core_dump)(target_sig, env) == 0); } if (core_dumped) { /* we already dumped the core of target process, we don't want @@ -503,6 +504,7 @@ int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info) static void host_signal_handler(int host_signum, siginfo_t *info, void *puc) { + CPUArchState *env = thread_cpu->env_ptr; int sig; target_siginfo_t tinfo; @@ -522,9 +524,9 @@ static void host_signal_handler(int host_signum, siginfo_t *info, fprintf(stderr, "qemu: got signal %d\n", sig); #endif host_to_target_siginfo_noswap(&tinfo, info); - if (queue_signal(thread_env, sig, &tinfo) == 1) { + if (queue_signal(env, sig, &tinfo) == 1) { /* interrupt the virtual CPU as soon as possible */ - cpu_exit(ENV_GET_CPU(thread_env)); + cpu_exit(thread_cpu); } } diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h new file mode 100644 index 0000000000..5a620a2bb7 --- /dev/null +++ b/linux-user/sparc/target_cpu.h @@ -0,0 +1,36 @@ +/* + * SPARC specific CPU ABI and functions for linux-user + * + * Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> + * Copyright (C) 2003-2005 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp) +{ + if (newsp) { + env->regwptr[22] = newsp; + } + env->regwptr[0] = 0; + /* FIXME: Do we also need to clear CF? */ + /* XXXXX */ + printf("HELPME: %s:%d\n", __FILE__, __LINE__); +} + +/* TODO: need to implement cpu_set_tls() */ + +#endif diff --git a/linux-user/sparc64/target_cpu.h b/linux-user/sparc64/target_cpu.h new file mode 100644 index 0000000000..b22263d2db --- /dev/null +++ b/linux-user/sparc64/target_cpu.h @@ -0,0 +1 @@ +#include "../sparc/target_cpu.h" diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a6a7828cc3..00a0390ea9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4250,8 +4250,8 @@ static void *clone_func(void *arg) env = info->env; cpu = ENV_GET_CPU(env); - thread_env = env; - ts = (TaskState *)thread_env->opaque; + thread_cpu = cpu; + ts = (TaskState *)env->opaque; info->tid = gettid(); cpu->host_tid = info->tid; task_settid(ts); @@ -5132,6 +5132,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg5, abi_long arg6, abi_long arg7, abi_long arg8) { +#ifdef CONFIG_USE_NPTL + CPUState *cpu = ENV_GET_CPU(cpu_env); +#endif abi_long ret; struct stat st; struct statfs stfs; @@ -5146,42 +5149,43 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, switch(num) { case TARGET_NR_exit: #ifdef CONFIG_USE_NPTL - /* In old applications this may be used to implement _exit(2). - However in threaded applictions it is used for thread termination, - and _exit_group is used for application termination. - Do thread termination if we have more then one thread. */ - /* FIXME: This probably breaks if a signal arrives. We should probably - be disabling signals. */ - if (first_cpu->next_cpu) { - TaskState *ts; - CPUArchState **lastp; - CPUArchState *p; - - cpu_list_lock(); - lastp = &first_cpu; - p = first_cpu; - while (p && p != (CPUArchState *)cpu_env) { - lastp = &p->next_cpu; - p = p->next_cpu; - } - /* If we didn't find the CPU for this thread then something is - horribly wrong. */ - if (!p) - abort(); - /* Remove the CPU from the list. */ - *lastp = p->next_cpu; - cpu_list_unlock(); - ts = ((CPUArchState *)cpu_env)->opaque; - if (ts->child_tidptr) { - put_user_u32(0, ts->child_tidptr); - sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, - NULL, NULL, 0); - } - thread_env = NULL; - object_unref(OBJECT(ENV_GET_CPU(cpu_env))); - g_free(ts); - pthread_exit(NULL); - } + /* In old applications this may be used to implement _exit(2). + However in threaded applictions it is used for thread termination, + and _exit_group is used for application termination. + Do thread termination if we have more then one thread. */ + /* FIXME: This probably breaks if a signal arrives. We should probably + be disabling signals. */ + if (first_cpu->next_cpu) { + TaskState *ts; + CPUState **lastp; + CPUState *p; + + cpu_list_lock(); + lastp = &first_cpu; + p = first_cpu; + while (p && p != cpu) { + lastp = &p->next_cpu; + p = p->next_cpu; + } + /* If we didn't find the CPU for this thread then something is + horribly wrong. */ + if (!p) { + abort(); + } + /* Remove the CPU from the list. */ + *lastp = p->next_cpu; + cpu_list_unlock(); + ts = ((CPUArchState *)cpu_env)->opaque; + if (ts->child_tidptr) { + put_user_u32(0, ts->child_tidptr); + sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, + NULL, NULL, 0); + } + thread_cpu = NULL; + object_unref(OBJECT(ENV_GET_CPU(cpu_env))); + g_free(ts); + pthread_exit(NULL); + } #endif #ifdef TARGET_GPROF _mcleanup(); diff --git a/linux-user/unicore32/target_cpu.h b/linux-user/unicore32/target_cpu.h new file mode 100644 index 0000000000..fb7908719f --- /dev/null +++ b/linux-user/unicore32/target_cpu.h @@ -0,0 +1,27 @@ +/* + * UniCore32 specific CPU ABI and functions for linux-user + * + * Copyright (C) 2010-2012 Guan Xuetao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) any + * later version. See the COPYING file in the top-level directory. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUUniCore32State *env, target_ulong newsp) +{ + if (newsp) { + env->regs[29] = newsp; + } + env->regs[0] = 0; +} + +static inline void cpu_set_tls(CPUUniCore32State *env, target_ulong newtls) +{ + env->regs[16] = newtls; +} + +#endif diff --git a/linux-user/x86_64/target_cpu.h b/linux-user/x86_64/target_cpu.h new file mode 100644 index 0000000000..9ec7cbb7a4 --- /dev/null +++ b/linux-user/x86_64/target_cpu.h @@ -0,0 +1 @@ +#include "../i386/target_cpu.h" |