diff options
Diffstat (limited to 'linux-user/main.c')
-rw-r--r-- | linux-user/main.c | 455 |
1 files changed, 305 insertions, 150 deletions
diff --git a/linux-user/main.c b/linux-user/main.c index af99d0455..baa90731d 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -28,11 +28,6 @@ #define DEBUG_LOGFILE "/tmp/qemu.log" -#ifdef __APPLE__ -#include <crt_externs.h> -# define environ (*_NSGetEnviron()) -#endif - static const char *interp_prefix = CONFIG_QEMU_PREFIX; const char *qemu_uname_release = CONFIG_UNAME_RELEASE; @@ -45,12 +40,20 @@ const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2"; /* for recent libc, we add these dummy symbols which are not declared when generating a linked object (bug in ld ?) */ #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC) -long __preinit_array_start[0]; -long __preinit_array_end[0]; -long __init_array_start[0]; -long __init_array_end[0]; -long __fini_array_start[0]; -long __fini_array_end[0]; +asm(".globl __preinit_array_start\n" + ".globl __preinit_array_end\n" + ".globl __init_array_start\n" + ".globl __init_array_end\n" + ".globl __fini_array_start\n" + ".globl __fini_array_end\n" + ".section \".rodata\"\n" + "__preinit_array_start:\n" + "__preinit_array_end:\n" + "__init_array_start:\n" + "__init_array_end:\n" + "__fini_array_start:\n" + "__fini_array_end:\n" + ".long 0\n"); #endif /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so @@ -144,38 +147,58 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit, p[1] = tswapl(e2); } -static void set_gate(void *ptr, unsigned int type, unsigned int dpl, - unsigned long addr, unsigned int sel) +#if TARGET_X86_64 +uint64_t idt_table[512]; + +static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, + uint64_t addr, unsigned int sel) { - unsigned int e1, e2; - uint32_t *p; + uint32_t *p, e1, e2; e1 = (addr & 0xffff) | (sel << 16); e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); p = ptr; - p[0] = tswapl(e1); - p[1] = tswapl(e2); + p[0] = tswap32(e1); + p[1] = tswap32(e2); + p[2] = tswap32(addr >> 32); + p[3] = 0; } - -uint64_t gdt_table[6]; +/* only dpl matters as we do only user space emulation */ +static void set_idt(int n, unsigned int dpl) +{ + set_gate64(idt_table + n * 2, 0, dpl, 0, 0); +} +#else uint64_t idt_table[256]; +static void set_gate(void *ptr, unsigned int type, unsigned int dpl, + uint32_t addr, unsigned int sel) +{ + uint32_t *p, e1, e2; + e1 = (addr & 0xffff) | (sel << 16); + e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); + p = ptr; + p[0] = tswap32(e1); + p[1] = tswap32(e2); +} + /* only dpl matters as we do only user space emulation */ static void set_idt(int n, unsigned int dpl) { set_gate(idt_table + n, 0, dpl, 0, 0); } +#endif void cpu_loop(CPUX86State *env) { int trapnr; - target_ulong pc; + abi_ulong pc; target_siginfo_t info; for(;;) { trapnr = cpu_x86_exec(env); switch(trapnr) { case 0x80: - /* linux syscall */ + /* linux syscall from int $0x80 */ env->regs[R_EAX] = do_syscall(env, env->regs[R_EAX], env->regs[R_EBX], @@ -185,6 +208,20 @@ void cpu_loop(CPUX86State *env) env->regs[R_EDI], env->regs[R_EBP]); break; +#ifndef TARGET_ABI32 + case EXCP_SYSCALL: + /* linux syscall from syscall intruction */ + env->regs[R_EAX] = do_syscall(env, + env->regs[R_EAX], + env->regs[R_EDI], + env->regs[R_ESI], + env->regs[R_EDX], + env->regs[10], + env->regs[8], + env->regs[9]); + env->eip = env->exception_next_eip; + break; +#endif case EXCP0B_NOSEG: case EXCP0C_STACK: info.si_signo = SIGBUS; @@ -194,6 +231,7 @@ void cpu_loop(CPUX86State *env) queue_signal(info.si_signo, &info); break; case EXCP0D_GPF: + /* XXX: potential problem if ABI32 */ #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_fault(env); @@ -305,11 +343,11 @@ void cpu_loop(CPUX86State *env) #ifdef TARGET_ARM /* XXX: find a better solution */ -extern void tb_invalidate_page_range(target_ulong start, target_ulong end); +extern void tb_invalidate_page_range(abi_ulong start, abi_ulong end); -static void arm_cache_flush(target_ulong start, target_ulong last) +static void arm_cache_flush(abi_ulong start, abi_ulong last) { - target_ulong addr, last1; + abi_ulong addr, last1; if (last < start) return; @@ -342,7 +380,8 @@ void cpu_loop(CPUARMState *env) /* we handle the FPU emulation here, as Linux */ /* we get the opcode */ - opcode = tget32(env->regs[15]); + /* FIXME - what to do if get_user() fails? */ + get_user_u32(opcode, env->regs[15]); if (EmulateAll(opcode, &ts->fpa, env) == 0) { info.si_signo = SIGILL; @@ -363,20 +402,24 @@ void cpu_loop(CPUARMState *env) /* system call */ if (trapnr == EXCP_BKPT) { if (env->thumb) { - insn = tget16(env->regs[15]); + /* FIXME - what to do if get_user() fails? */ + get_user_u16(insn, env->regs[15]); n = insn & 0xff; env->regs[15] += 2; } else { - insn = tget32(env->regs[15]); + /* FIXME - what to do if get_user() fails? */ + get_user_u32(insn, env->regs[15]); n = (insn & 0xf) | ((insn >> 4) & 0xff0); env->regs[15] += 4; } } else { if (env->thumb) { - insn = tget16(env->regs[15] - 2); + /* FIXME - what to do if get_user() fails? */ + get_user_u16(insn, env->regs[15] - 2); n = insn & 0xff; } else { - insn = tget32(env->regs[15] - 4); + /* FIXME - what to do if get_user() fails? */ + get_user_u32(insn, env->regs[15] - 4); n = insn & 0xffffff; } } @@ -474,7 +517,7 @@ static inline int get_reg_index(CPUSPARCState *env, int cwp, int index) static inline void save_window_offset(CPUSPARCState *env, int cwp1) { unsigned int i; - target_ulong sp_ptr; + abi_ulong sp_ptr; sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; #if defined(DEBUG_WIN) @@ -482,8 +525,9 @@ static inline void save_window_offset(CPUSPARCState *env, int cwp1) (int)sp_ptr, cwp1); #endif for(i = 0; i < 16; i++) { - tputl(sp_ptr, env->regbase[get_reg_index(env, cwp1, 8 + i)]); - sp_ptr += sizeof(target_ulong); + /* FIXME - what to do if put_user() fails? */ + put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr); + sp_ptr += sizeof(abi_ulong); } } @@ -505,7 +549,7 @@ static void save_window(CPUSPARCState *env) static void restore_window(CPUSPARCState *env) { unsigned int new_wim, i, cwp1; - target_ulong sp_ptr; + abi_ulong sp_ptr; new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) & ((1LL << NWINDOWS) - 1); @@ -518,8 +562,9 @@ static void restore_window(CPUSPARCState *env) (int)sp_ptr, cwp1); #endif for(i = 0; i < 16; i++) { - env->regbase[get_reg_index(env, cwp1, 8 + i)] = tgetl(sp_ptr); - sp_ptr += sizeof(target_ulong); + /* FIXME - what to do if get_user() fails? */ + get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr); + sp_ptr += sizeof(abi_ulong); } env->wim = new_wim; #ifdef TARGET_SPARC64 @@ -564,6 +609,7 @@ void cpu_loop (CPUSPARCState *env) case 0x88: case 0x90: #else + case 0x110: case 0x16d: #endif ret = do_syscall (env, env->gregs[1], @@ -571,14 +617,14 @@ void cpu_loop (CPUSPARCState *env) env->regwptr[2], env->regwptr[3], env->regwptr[4], env->regwptr[5]); if ((unsigned int)ret >= (unsigned int)(-515)) { -#ifdef TARGET_SPARC64 +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc |= PSR_CARRY; #else env->psr |= PSR_CARRY; #endif ret = -ret; } else { -#ifdef TARGET_SPARC64 +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc &= ~PSR_CARRY; #else env->psr &= ~PSR_CARRY; @@ -590,6 +636,9 @@ void cpu_loop (CPUSPARCState *env) env->npc = env->npc + 4; break; case 0x83: /* flush windows */ +#ifdef TARGET_ABI32 + case 0x103: +#endif flush_windows(env); /* next instruction */ env->pc = env->npc; @@ -634,6 +683,16 @@ void cpu_loop (CPUSPARCState *env) queue_signal(info.si_signo, &info); } break; +#ifndef TARGET_ABI32 + case 0x16e: + flush_windows(env); + sparc64_get_context(env); + break; + case 0x16f: + flush_windows(env); + sparc64_set_context(env); + break; +#endif #endif case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ @@ -773,7 +832,7 @@ void cpu_loop(CPUPPCState *env) break; case POWERPC_EXCP_ISI: /* Instruction storage exception */ EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n", - env->spr[SPR_DAR]); + env->spr[SPR_SRR0]); /* XXX: check this */ switch (env->error_code & 0xFF000000) { case 0x40000000: @@ -817,12 +876,6 @@ void cpu_loop(CPUPPCState *env) switch (env->error_code & ~0xF) { case POWERPC_EXCP_FP: EXCP_DUMP(env, "Floating point program exception\n"); - /* Set FX */ - env->fpscr[7] |= 0x8; - /* Finally, update FEX */ - if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) & - ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3))) - env->fpscr[7] |= 0x4; info.si_signo = TARGET_SIGFPE; info.si_errno = 0; switch (env->error_code & 0xF) { @@ -842,7 +895,7 @@ void cpu_loop(CPUPPCState *env) case POWERPC_EXCP_FP_VXSOFT: info.si_code = TARGET_FPE_FLTINV; break; - case POWERPC_EXCP_FP_VXNAN: + case POWERPC_EXCP_FP_VXSNAN: case POWERPC_EXCP_FP_VXISI: case POWERPC_EXCP_FP_VXIDI: case POWERPC_EXCP_FP_VXIMZ: @@ -965,7 +1018,6 @@ void cpu_loop(CPUPPCState *env) } } break; -#if defined(TARGET_PPCEMB) case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */ EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n"); info.si_signo = TARGET_SIGILL; @@ -995,8 +1047,6 @@ void cpu_loop(CPUPPCState *env) cpu_abort(env, "Reset interrupt while in user mode. " "Aborting\n"); break; -#endif /* defined(TARGET_PPCEMB) */ -#if defined(TARGET_PPC64) /* PowerPC 64 */ case POWERPC_EXCP_DSEG: /* Data segment exception */ cpu_abort(env, "Data segment exception while in user mode. " "Aborting\n"); @@ -1005,19 +1055,17 @@ void cpu_loop(CPUPPCState *env) cpu_abort(env, "Instruction segment exception " "while in user mode. Aborting\n"); break; -#endif /* defined(TARGET_PPC64) */ -#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ + /* PowerPC 64 with hypervisor mode support */ case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ cpu_abort(env, "Hypervisor decrementer interrupt " "while in user mode. Aborting\n"); break; -#endif /* defined(TARGET_PPC64H) */ case POWERPC_EXCP_TRACE: /* Trace exception */ /* Nothing to do: * we use this exception to emulate step-by-step execution mode. */ break; -#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ + /* PowerPC 64 with hypervisor mode support */ case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ cpu_abort(env, "Hypervisor data storage exception " "while in user mode. Aborting\n"); @@ -1034,7 +1082,6 @@ void cpu_loop(CPUPPCState *env) cpu_abort(env, "Hypervisor instruction segment exception " "while in user mode. Aborting\n"); break; -#endif /* defined(TARGET_PPC64H) */ case POWERPC_EXCP_VPU: /* Vector unavailable exception */ EXCP_DUMP(env, "No Altivec instructions allowed\n"); info.si_signo = TARGET_SIGILL; @@ -1480,17 +1527,18 @@ void cpu_loop(CPUMIPSState *env) ret = -ENOSYS; } else { int nb_args; - target_ulong sp_reg; - target_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0; + abi_ulong sp_reg; + abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0; nb_args = mips_syscall_args[syscall_num]; sp_reg = env->gpr[29][env->current_tc]; switch (nb_args) { /* these arguments are taken from the stack */ - case 8: arg8 = tgetl(sp_reg + 28); - case 7: arg7 = tgetl(sp_reg + 24); - case 6: arg6 = tgetl(sp_reg + 20); - case 5: arg5 = tgetl(sp_reg + 16); + /* FIXME - what to do if get_user() fails? */ + case 8: get_user_ual(arg8, sp_reg + 28); + case 7: get_user_ual(arg7, sp_reg + 24); + case 6: get_user_ual(arg6, sp_reg + 20); + case 5: get_user_ual(arg5, sp_reg + 16); default: break; } @@ -1565,10 +1613,77 @@ void cpu_loop (CPUState *env) env->gregs[6], env->gregs[7], env->gregs[0], - 0); + env->gregs[1]); env->gregs[0] = ret; env->pc += 2; break; + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_DEBUG: + { + int sig; + + sig = gdb_handlesig (env, TARGET_SIGTRAP); + if (sig) + { + info.si_signo = sig; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(info.si_signo, &info); + } + } + break; + case 0xa0: + case 0xc0: + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->tea; + queue_signal(info.si_signo, &info); + break; + + default: + printf ("Unhandled trap: 0x%x\n", trapnr); + cpu_dump_state(env, stderr, fprintf, 0); + exit (1); + } + process_pending_signals (env); + } +} +#endif + +#ifdef TARGET_CRIS +void cpu_loop (CPUState *env) +{ + int trapnr, ret; + target_siginfo_t info; + + while (1) { + trapnr = cpu_cris_exec (env); + switch (trapnr) { + case 0xaa: + { + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->debug1; + queue_signal(info.si_signo, &info); + } + break; + case EXCP_BREAK: + ret = do_syscall(env, + env->regs[9], + env->regs[10], + env->regs[11], + env->regs[12], + env->regs[13], + env->pregs[7], + env->pregs[11]); + env->regs[10] = ret; + env->pc += 2; + break; case EXCP_DEBUG: { int sig; @@ -1789,11 +1904,14 @@ void usage(void) "-drop-ld-preload drop LD_PRELOAD for target process\n" "\n" "debug options:\n" -#ifdef USE_CODE_COPY - "-no-code-copy disable code copy acceleration\n" -#endif "-d options activate log (logfile=%s)\n" - "-p pagesize set the host page size to 'pagesize'\n", + "-p pagesize set the host page size to 'pagesize'\n" + "-strace log system calls\n" + "\n" + "environment variables:\n" + "QEMU_STRACE Print system calls and arguments similar to the\n" + " 'strace' program. Enable by setting to any value.\n" + , TARGET_ARCH, interp_prefix, x86_stack_size, @@ -1881,25 +1999,17 @@ int main(int argc, char **argv) } else if (!strcmp(r, "cpu")) { cpu_model = argv[optind++]; if (strcmp(cpu_model, "?") == 0) { -#if defined(TARGET_PPC) - ppc_cpu_list(stdout, &fprintf); -#elif defined(TARGET_ARM) - arm_cpu_list(); -#elif defined(TARGET_MIPS) - mips_cpu_list(stdout, &fprintf); -#elif defined(TARGET_SPARC) - sparc_cpu_list(stdout, &fprintf); +/* XXX: implement xxx_cpu_list for targets that still miss it */ +#if defined(cpu_list) + cpu_list(stdout, &fprintf); #endif _exit(1); } } else if (!strcmp(r, "drop-ld-preload")) { drop_ld_preload = 1; + } else if (!strcmp(r, "strace")) { + do_strace = 1; } else -#ifdef USE_CODE_COPY - if (!strcmp(r, "no-code-copy")) { - code_copy_enabled = 0; - } else -#endif { usage(); } @@ -1917,11 +2027,52 @@ int main(int argc, char **argv) /* Scan interp_prefix dir for replacement files. */ init_paths(interp_prefix); + if (cpu_model == NULL) { +#if defined(TARGET_I386) +#ifdef TARGET_X86_64 + cpu_model = "qemu64"; +#else + cpu_model = "qemu32"; +#endif +#elif defined(TARGET_ARM) + cpu_model = "arm926"; +#elif defined(TARGET_M68K) + cpu_model = "any"; +#elif defined(TARGET_SPARC) +#ifdef TARGET_SPARC64 + cpu_model = "TI UltraSparc II"; +#else + cpu_model = "Fujitsu MB86904"; +#endif +#elif defined(TARGET_MIPS) +#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) + cpu_model = "20Kc"; +#else + cpu_model = "24Kf"; +#endif +#elif defined(TARGET_PPC) +#ifdef TARGET_PPC64 + cpu_model = "970"; +#else + cpu_model = "750"; +#endif +#else + cpu_model = "any"; +#endif + } /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ - env = cpu_init(); + env = cpu_init(cpu_model); + if (!env) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } global_env = env; + if (getenv("QEMU_STRACE")) { + do_strace = 1; + } + wrk = environ; while (*(wrk++)) environ_count++; @@ -1950,14 +2101,17 @@ int main(int argc, char **argv) if (loglevel) { page_dump(logfile); - fprintf(logfile, "start_brk 0x%08lx\n" , info->start_brk); - fprintf(logfile, "end_code 0x%08lx\n" , info->end_code); - fprintf(logfile, "start_code 0x%08lx\n" , info->start_code); - fprintf(logfile, "start_data 0x%08lx\n" , info->start_data); - fprintf(logfile, "end_data 0x%08lx\n" , info->end_data); - fprintf(logfile, "start_stack 0x%08lx\n" , info->start_stack); - fprintf(logfile, "brk 0x%08lx\n" , info->brk); - fprintf(logfile, "entry 0x%08lx\n" , info->entry); + fprintf(logfile, "start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk); + fprintf(logfile, "end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code); + fprintf(logfile, "start_code 0x" TARGET_ABI_FMT_lx "\n", + info->start_code); + fprintf(logfile, "start_data 0x" TARGET_ABI_FMT_lx "\n", + info->start_data); + fprintf(logfile, "end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data); + fprintf(logfile, "start_stack 0x" TARGET_ABI_FMT_lx "\n", + info->start_stack); + fprintf(logfile, "brk 0x" TARGET_ABI_FMT_lx "\n", info->brk); + fprintf(logfile, "entry 0x" TARGET_ABI_FMT_lx "\n", info->entry); } target_set_brk(info->brk); @@ -1980,12 +2134,22 @@ int main(int argc, char **argv) env->cr[4] |= CR4_OSFXSR_MASK; env->hflags |= HF_OSFXSR_MASK; } +#ifndef TARGET_ABI32 + /* enable 64 bit mode if possible */ + if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) { + fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n"); + exit(1); + } + env->cr[4] |= CR4_PAE_MASK; + env->efer |= MSR_EFER_LMA | MSR_EFER_LME; + env->hflags |= HF_LMA_MASK; +#endif /* flags setup : we activate the IRQs by default as in user mode */ env->eflags |= IF_MASK; /* linux register setup */ -#if defined(TARGET_X86_64) +#ifndef TARGET_ABI32 env->regs[R_EAX] = regs->rax; env->regs[R_EBX] = regs->rbx; env->regs[R_ECX] = regs->rcx; @@ -2033,29 +2197,44 @@ int main(int argc, char **argv) set_idt(0x80, 3); /* linux segment setup */ - env->gdt.base = h2g(gdt_table); - env->gdt.limit = sizeof(gdt_table) - 1; - write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | - (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); - write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | - (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); + { + uint64_t *gdt_table; + gdt_table = qemu_mallocz(sizeof(uint64_t) * TARGET_GDT_ENTRIES); + env->gdt.base = h2g((unsigned long)gdt_table); + env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; +#ifdef TARGET_ABI32 + write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | + (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); +#else + /* 64 bit code segment */ + write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | + DESC_L_MASK | + (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); +#endif + write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff, + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | + (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); + } cpu_x86_load_seg(env, R_CS, __USER_CS); + cpu_x86_load_seg(env, R_SS, __USER_DS); +#ifdef TARGET_ABI32 cpu_x86_load_seg(env, R_DS, __USER_DS); cpu_x86_load_seg(env, R_ES, __USER_DS); - cpu_x86_load_seg(env, R_SS, __USER_DS); cpu_x86_load_seg(env, R_FS, __USER_DS); cpu_x86_load_seg(env, R_GS, __USER_DS); - /* This hack makes Wine work... */ env->segs[R_FS].selector = 0; +#else + cpu_x86_load_seg(env, R_DS, 0); + cpu_x86_load_seg(env, R_ES, 0); + cpu_x86_load_seg(env, R_FS, 0); + cpu_x86_load_seg(env, R_GS, 0); +#endif #elif defined(TARGET_ARM) { int i; - if (cpu_model == NULL) - cpu_model = "arm926"; - cpu_arm_set_model(env, cpu_model); cpsr_write(env, regs->uregs[16], 0xffffffff); for(i = 0; i < 16; i++) { env->regs[i] = regs->uregs[i]; @@ -2064,20 +2243,6 @@ int main(int argc, char **argv) #elif defined(TARGET_SPARC) { int i; - const sparc_def_t *def; -#ifdef TARGET_SPARC64 - if (cpu_model == NULL) - cpu_model = "TI UltraSparc II"; -#else - if (cpu_model == NULL) - cpu_model = "Fujitsu MB86904"; -#endif - sparc_find_by_name(cpu_model, &def); - if (def == NULL) { - fprintf(stderr, "Unable to find Sparc CPU definition\n"); - exit(1); - } - cpu_sparc_register(env, def); env->pc = regs->pc; env->npc = regs->npc; env->y = regs->y; @@ -2088,25 +2253,14 @@ int main(int argc, char **argv) } #elif defined(TARGET_PPC) { - ppc_def_t *def; int i; - /* Choose and initialise CPU */ - if (cpu_model == NULL) - cpu_model = "750"; - ppc_find_by_name(cpu_model, &def); - if (def == NULL) { - cpu_abort(env, - "Unable to find PowerPC CPU definition\n"); - } - cpu_ppc_register(env, def); - - for (i = 0; i < 32; i++) { - if (i != 12 && i != 6 && i != 13) - env->msr[i] = (regs->msr >> i) & 1; - } #if defined(TARGET_PPC64) - msr_sf = 1; +#if defined(TARGET_ABI32) + env->msr &= ~((target_ulong)1 << MSR_SF); +#else + env->msr |= (target_ulong)1 << MSR_SF; +#endif #endif env->nip = regs->nip; for(i = 0; i < 32; i++) { @@ -2115,12 +2269,6 @@ int main(int argc, char **argv) } #elif defined(TARGET_M68K) { - if (cpu_model == NULL) - cpu_model = "any"; - if (cpu_m68k_set_model(env, cpu_model)) { - cpu_abort(cpu_single_env, - "Unable to find m68k CPU definition\n"); - } env->pc = regs->pc; env->dregs[0] = regs->d0; env->dregs[1] = regs->d1; @@ -2143,21 +2291,8 @@ int main(int argc, char **argv) } #elif defined(TARGET_MIPS) { - mips_def_t *def; int i; - /* Choose and initialise CPU */ - if (cpu_model == NULL) -#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) - cpu_model = "20Kc"; -#else - cpu_model = "24Kf"; -#endif - mips_find_by_name(cpu_model, &def); - if (def == NULL) - cpu_abort(env, "Unable to find MIPS CPU definition\n"); - cpu_mips_register(env, def); - for(i = 0; i < 32; i++) { env->gpr[i][env->current_tc] = regs->regs[i]; } @@ -2177,13 +2312,33 @@ int main(int argc, char **argv) int i; for(i = 0; i < 28; i++) { - env->ir[i] = ((target_ulong *)regs)[i]; + env->ir[i] = ((abi_ulong *)regs)[i]; } env->ipr[IPR_USP] = regs->usp; env->ir[30] = regs->usp; env->pc = regs->pc; env->unique = regs->unique; } +#elif defined(TARGET_CRIS) + { + env->regs[0] = regs->r0; + env->regs[1] = regs->r1; + env->regs[2] = regs->r2; + env->regs[3] = regs->r3; + env->regs[4] = regs->r4; + env->regs[5] = regs->r5; + env->regs[6] = regs->r6; + env->regs[7] = regs->r7; + env->regs[8] = regs->r8; + env->regs[9] = regs->r9; + env->regs[10] = regs->r10; + env->regs[11] = regs->r11; + env->regs[12] = regs->r12; + env->regs[13] = regs->r13; + env->regs[14] = info->start_stack; + env->regs[15] = regs->acr; + env->pc = regs->erp; + } #else #error unsupported target CPU #endif |