Move clone() register setup to target specific code. Handle fork-like clone.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4623 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2008-05-30 17:22:15 +00:00
parent a4a99d71b2
commit 6e68e076e7
10 changed files with 92 additions and 58 deletions

View File

@ -2744,64 +2744,8 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
first_task_state = ts;
/* we create a new CPU instance. */
new_env = cpu_copy(env);
#if defined(TARGET_I386)
if (!newsp)
newsp = env->regs[R_ESP];
new_env->regs[R_ESP] = newsp;
new_env->regs[R_EAX] = 0;
#elif defined(TARGET_ARM)
if (!newsp)
newsp = env->regs[13];
new_env->regs[13] = newsp;
new_env->regs[0] = 0;
#elif defined(TARGET_SPARC)
if (!newsp)
newsp = env->regwptr[22];
new_env->regwptr[22] = newsp;
new_env->regwptr[0] = 0;
/* XXXXX */
printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
#elif defined(TARGET_M68K)
if (!newsp)
newsp = env->aregs[7];
new_env->aregs[7] = newsp;
new_env->dregs[0] = 0;
/* ??? is this sufficient? */
#elif defined(TARGET_MIPS)
if (!newsp)
newsp = env->gpr[env->current_tc][29];
new_env->gpr[env->current_tc][29] = newsp;
#elif defined(TARGET_PPC)
if (!newsp)
newsp = env->gpr[1];
new_env->gpr[1] = newsp;
{
int i;
for (i = 7; i < 32; i++)
new_env->gpr[i] = 0;
}
#elif defined(TARGET_SH4)
if (!newsp)
newsp = env->gregs[15];
new_env->gregs[15] = newsp;
/* XXXXX */
#elif defined(TARGET_ALPHA)
if (!newsp)
newsp = env->ir[30];
new_env->ir[30] = newsp;
/* ? */
{
int i;
for (i = 7; i < 30; i++)
new_env->ir[i] = 0;
}
#elif defined(TARGET_CRIS)
if (!newsp)
newsp = env->regs[14];
new_env->regs[14] = newsp;
#else
#error unsupported target CPU
#endif
/* Init regs that differ from the parent. */
cpu_clone_regs(new_env, newsp);
new_env->opaque = ts;
#ifdef __ia64__
ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
@ -2813,6 +2757,9 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
if ((flags & ~CSIGNAL) != 0)
return -EINVAL;
ret = fork();
if (ret == 0) {
cpu_clone_regs(env, newsp);
}
}
return ret;
}

View File

@ -311,6 +311,15 @@ static inline int cpu_mmu_index (CPUState *env)
return (env->ps >> 3) & 3;
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
if (!newsp)
env->ir[30] = newsp;
/* FIXME: Zero syscall return value. */
}
#endif
#include "cpu-all.h"
enum {

View File

@ -408,6 +408,15 @@ static inline int cpu_mmu_index (CPUState *env)
return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
if (!newsp)
env->regs[13] = newsp;
env->regs[0] = 0;
}
#endif
#include "cpu-all.h"
#endif

View File

@ -218,6 +218,15 @@ static inline int cpu_mmu_index (CPUState *env)
return !!(env->pregs[PR_CCS] & U_FLAG);
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
if (!newsp)
env->regs[14] = newsp;
env->regs[10] = 0;
}
#endif
/* Support function regs. */
#define SFR_RW_GC_CFG 0][0
#define SFR_RW_MM_CFG env->pregs[PR_SRS]][0

View File

@ -734,6 +734,15 @@ typedef struct CCTable {
extern CCTable cc_table[];
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
if (!newsp)
env->regs[R_ESP] = newsp;
env->regs[R_EAX] = 0;
}
#endif
#include "cpu-all.h"
#include "svm.h"

View File

@ -226,6 +226,15 @@ static inline int cpu_mmu_index (CPUState *env)
return (env->sr & SR_S) == 0 ? 1 : 0;
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
if (!newsp)
env->aregs[7] = newsp;
env->dregs[0] = 0;
}
#endif
#include "cpu-all.h"
#endif

View File

@ -500,6 +500,16 @@ static inline int cpu_mmu_index (CPUState *env)
return env->hflags & MIPS_HFLAG_KSU;
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
if (!newsp)
env->gpr[env->current_tc][29] = newsp;
env->gpr[env->current_tc][7] = 0;
env->gpr[env->current_tc][2] = 0;
}
#endif
#include "cpu-all.h"
/* Memory access type :

View File

@ -822,6 +822,17 @@ static inline int cpu_mmu_index (CPUState *env)
return env->mmu_idx;
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
int i;
if (!newsp)
env->gpr[1] = newsp;
for (i = 7; i < 32; i++)
env->gpr[i] = 0;
}
#endif
#include "cpu-all.h"
/*****************************************************************************/

View File

@ -143,6 +143,15 @@ static inline int cpu_mmu_index (CPUState *env)
return (env->sr & SR_MD) == 0 ? 1 : 0;
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
if (!newsp)
env->gregs[15] = newsp;
env->gregs[0] = 0;
}
#endif
#include "cpu-all.h"
/* Memory access type */

View File

@ -403,6 +403,18 @@ static inline int cpu_fpu_enabled(CPUState *env1)
#endif
}
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *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__);
}
#endif
#include "cpu-all.h"
#endif