From nobody Tue Feb 10 14:32:21 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 15250798138501009.7800683274766; Mon, 30 Apr 2018 02:16:53 -0700 (PDT) Received: from localhost ([::1]:58548 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fD4vU-0002fe-Tm for importer@patchew.org; Mon, 30 Apr 2018 05:16:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33248) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fD4qR-0006fo-0k for qemu-devel@nongnu.org; Mon, 30 Apr 2018 05:11:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fD4qJ-0006UU-RW for qemu-devel@nongnu.org; Mon, 30 Apr 2018 05:11:38 -0400 Received: from mout.kundenserver.de ([217.72.192.74]:45093) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fD4q5-0006DU-Su; Mon, 30 Apr 2018 05:11:18 -0400 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue102 [212.227.15.183]) with ESMTPSA (Nemesis) id 0LbIy2-1eWcT63MxW-00ksy6; Mon, 30 Apr 2018 11:11:11 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Mon, 30 Apr 2018 11:10:19 +0200 Message-Id: <20180430091037.13878-25-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180430091037.13878-1-laurent@vivier.eu> References: <20180430091037.13878-1-laurent@vivier.eu> X-Provags-ID: V03:K1:2Tz8bqAvXdSFwNPEx9Bg6I+1UJRbTyQBV/thlU3F1d5jGKVEhyZ oDumIhzoiDXzHPNhiuF6/jIkxjZMSbEPq2/D3IlvFU4kdnkSIsIO7cd9sGtfpBRLCMcSbSo ErmtJWKmfQ+L2Ita4xntgW1flceliDz28YaI80YSBoSdZVJ4CJfZpL52ONGloOS1kjw+Sv4 ms2T+F45l0N+EooTq/FvQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:ph+WpGTxmk0=:66aMSTXAT4UMDS8P3pDdAS QE5GBJJMv6QEYP914bkkaEzOEKQGgP/IZdwhHJ1V90OzObcYU6K6N9mfCSbI0GO4aogF2moO9 rNg+7X4kB1v8C/gVSzI8Vv80sNwV0xSuqEWm3QuRjpNIJH7XaqzSBFDWzbJLSscTzNWb1wrne /8P4wACwN+syT9IL2uvHxGVwPszjC5YKBCveP3hOKjdQh8ytjIUO2V3UR9YFHNuXHL/il0kQ5 AsOMWBXixNrsIT+EcU7XzfZIEXCac+lABXBJf7j0Z9fXLPi3PXzbl53NAPdz8gjlDyZeNPUNK TtgaE+ICAE53VoFgmzgLx/2YX3vvqnsgzs2GFfM92yCuDo29UEnVzfpCQhsJ6aJx+L+mAaVVj +wI7k7Eo+FUl+T5uh2n0exl1aOaJ8HRYNKfRHRAWex2NBINBhQKJwmQ4XIUXZtHhAStUt6nfR CN/sQCzX0ZZs2XyalKlmQ1+1Bmlpc7B19L/l2UmLug860G9UNA0BIaVsBtJYT+IFrCTjwmptE oj7VNrk+rmYDyGRWHFUjVOreqqvVZayFy/40vDgW3eL7vHV28IFuI5/4ZCH8XTGJHqBq9dEj2 +fZZ/0iYXmrEzMnhFbWOctwIOqMMnOTyNDR+jPxYFgWbjALYDlqFFtDvvvtrd7/IsqZ1Wow4o 5499h/9X1bN0xGjBFoRxFu0b0nmE0KD434+xTCBRJwp4fgrrBr4kvIZgBwe2uuJNs+tI= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 217.72.192.74 Subject: [Qemu-devel] [PULL 24/42] linux-user: move i386/x86_64 cpu loop to i386 directory X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-s390x@nongnu.org, Riku Voipio , Laurent Vivier , Cornelia Huck Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" No code change, only move code from main.c to i386/cpu_loop.c. Include i386/cpu_loop.c in x86_64/cpu_loop.c to avoid to duplicate code. Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson Message-Id: <20180411185651.21351-3-laurent@vivier.eu> --- linux-user/i386/cpu_loop.c | 343 +++++++++++++++++++++++++++++++++++++++= +++ linux-user/main.c | 348 +--------------------------------------= ---- linux-user/x86_64/cpu_loop.c | 8 +- 3 files changed, 345 insertions(+), 354 deletions(-) diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c index b7700a5561..2374abfd0b 100644 --- a/linux-user/i386/cpu_loop.c +++ b/linux-user/i386/cpu_loop.c @@ -21,6 +21,349 @@ #include "qemu.h" #include "cpu_loop-common.h" =20 +/***********************************************************/ +/* CPUX86 core interface */ + +uint64_t cpu_get_tsc(CPUX86State *env) +{ + return cpu_get_host_ticks(); +} + +static void write_dt(void *ptr, unsigned long addr, unsigned long limit, + int flags) +{ + unsigned int e1, e2; + uint32_t *p; + e1 =3D (addr << 16) | (limit & 0xffff); + e2 =3D ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f00= 00); + e2 |=3D flags; + p =3D ptr; + p[0] =3D tswap32(e1); + p[1] =3D tswap32(e2); +} + +static uint64_t *idt_table; +#ifdef TARGET_X86_64 +static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, + uint64_t addr, unsigned int sel) +{ + uint32_t *p, e1, e2; + e1 =3D (addr & 0xffff) | (sel << 16); + e2 =3D (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); + p =3D ptr; + p[0] =3D tswap32(e1); + p[1] =3D tswap32(e2); + p[2] =3D tswap32(addr >> 32); + p[3] =3D 0; +} +/* 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 +static void set_gate(void *ptr, unsigned int type, unsigned int dpl, + uint32_t addr, unsigned int sel) +{ + uint32_t *p, e1, e2; + e1 =3D (addr & 0xffff) | (sel << 16); + e2 =3D (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); + p =3D ptr; + p[0] =3D tswap32(e1); + p[1] =3D 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) +{ + CPUState *cs =3D CPU(x86_env_get_cpu(env)); + int trapnr; + abi_ulong pc; + abi_ulong ret; + target_siginfo_t info; + + for(;;) { + cpu_exec_start(cs); + trapnr =3D cpu_exec(cs); + cpu_exec_end(cs); + process_queued_cpu_work(cs); + + switch(trapnr) { + case 0x80: + /* linux syscall from int $0x80 */ + ret =3D do_syscall(env, + env->regs[R_EAX], + env->regs[R_EBX], + env->regs[R_ECX], + env->regs[R_EDX], + env->regs[R_ESI], + env->regs[R_EDI], + env->regs[R_EBP], + 0, 0); + if (ret =3D=3D -TARGET_ERESTARTSYS) { + env->eip -=3D 2; + } else if (ret !=3D -TARGET_QEMU_ESIGRETURN) { + env->regs[R_EAX] =3D ret; + } + break; +#ifndef TARGET_ABI32 + case EXCP_SYSCALL: + /* linux syscall from syscall instruction */ + ret =3D 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], + 0, 0); + if (ret =3D=3D -TARGET_ERESTARTSYS) { + env->eip -=3D 2; + } else if (ret !=3D -TARGET_QEMU_ESIGRETURN) { + env->regs[R_EAX] =3D ret; + } + break; +#endif + case EXCP0B_NOSEG: + case EXCP0C_STACK: + info.si_signo =3D TARGET_SIGBUS; + info.si_errno =3D 0; + info.si_code =3D TARGET_SI_KERNEL; + info._sifields._sigfault._addr =3D 0; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP0D_GPF: + /* XXX: potential problem if ABI32 */ +#ifndef TARGET_X86_64 + if (env->eflags & VM_MASK) { + handle_vm86_fault(env); + } else +#endif + { + info.si_signo =3D TARGET_SIGSEGV; + info.si_errno =3D 0; + info.si_code =3D TARGET_SI_KERNEL; + info._sifields._sigfault._addr =3D 0; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + } + break; + case EXCP0E_PAGE: + info.si_signo =3D TARGET_SIGSEGV; + info.si_errno =3D 0; + if (!(env->error_code & 1)) + info.si_code =3D TARGET_SEGV_MAPERR; + else + info.si_code =3D TARGET_SEGV_ACCERR; + info._sifields._sigfault._addr =3D env->cr[2]; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP00_DIVZ: +#ifndef TARGET_X86_64 + if (env->eflags & VM_MASK) { + handle_vm86_trap(env, trapnr); + } else +#endif + { + /* division by zero */ + info.si_signo =3D TARGET_SIGFPE; + info.si_errno =3D 0; + info.si_code =3D TARGET_FPE_INTDIV; + info._sifields._sigfault._addr =3D env->eip; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + } + break; + case EXCP01_DB: + case EXCP03_INT3: +#ifndef TARGET_X86_64 + if (env->eflags & VM_MASK) { + handle_vm86_trap(env, trapnr); + } else +#endif + { + info.si_signo =3D TARGET_SIGTRAP; + info.si_errno =3D 0; + if (trapnr =3D=3D EXCP01_DB) { + info.si_code =3D TARGET_TRAP_BRKPT; + info._sifields._sigfault._addr =3D env->eip; + } else { + info.si_code =3D TARGET_SI_KERNEL; + info._sifields._sigfault._addr =3D 0; + } + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + } + break; + case EXCP04_INTO: + case EXCP05_BOUND: +#ifndef TARGET_X86_64 + if (env->eflags & VM_MASK) { + handle_vm86_trap(env, trapnr); + } else +#endif + { + info.si_signo =3D TARGET_SIGSEGV; + info.si_errno =3D 0; + info.si_code =3D TARGET_SI_KERNEL; + info._sifields._sigfault._addr =3D 0; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + } + break; + case EXCP06_ILLOP: + info.si_signo =3D TARGET_SIGILL; + info.si_errno =3D 0; + info.si_code =3D TARGET_ILL_ILLOPN; + info._sifields._sigfault._addr =3D env->eip; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_DEBUG: + { + int sig; + + sig =3D gdb_handlesig(cs, TARGET_SIGTRAP); + if (sig) + { + info.si_signo =3D sig; + info.si_errno =3D 0; + info.si_code =3D TARGET_TRAP_BRKPT; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + } + } + break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; + default: + pc =3D env->segs[R_CS].base + env->eip; + EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - = aborting\n", + (long)pc, trapnr); + abort(); + } + process_pending_signals(env); + } +} + void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) { + env->cr[0] =3D CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; + env->hflags |=3D HF_PE_MASK | HF_CPL_MASK; + if (env->features[FEAT_1_EDX] & CPUID_SSE) { + env->cr[4] |=3D CR4_OSFXSR_MASK; + env->hflags |=3D HF_OSFXSR_MASK; + } +#ifndef TARGET_ABI32 + /* enable 64 bit mode if possible */ + if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) { + fprintf(stderr, "The selected x86 CPU does not support 64 bit mode= \n"); + exit(EXIT_FAILURE); + } + env->cr[4] |=3D CR4_PAE_MASK; + env->efer |=3D MSR_EFER_LMA | MSR_EFER_LME; + env->hflags |=3D HF_LMA_MASK; +#endif + + /* flags setup : we activate the IRQs by default as in user mode */ + env->eflags |=3D IF_MASK; + + /* linux register setup */ +#ifndef TARGET_ABI32 + env->regs[R_EAX] =3D regs->rax; + env->regs[R_EBX] =3D regs->rbx; + env->regs[R_ECX] =3D regs->rcx; + env->regs[R_EDX] =3D regs->rdx; + env->regs[R_ESI] =3D regs->rsi; + env->regs[R_EDI] =3D regs->rdi; + env->regs[R_EBP] =3D regs->rbp; + env->regs[R_ESP] =3D regs->rsp; + env->eip =3D regs->rip; +#else + env->regs[R_EAX] =3D regs->eax; + env->regs[R_EBX] =3D regs->ebx; + env->regs[R_ECX] =3D regs->ecx; + env->regs[R_EDX] =3D regs->edx; + env->regs[R_ESI] =3D regs->esi; + env->regs[R_EDI] =3D regs->edi; + env->regs[R_EBP] =3D regs->ebp; + env->regs[R_ESP] =3D regs->esp; + env->eip =3D regs->eip; +#endif + + /* linux interrupt setup */ +#ifndef TARGET_ABI32 + env->idt.limit =3D 511; +#else + env->idt.limit =3D 255; +#endif + env->idt.base =3D target_mmap(0, sizeof(uint64_t) * (env->idt.limit + = 1), + PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + idt_table =3D g2h(env->idt.base); + set_idt(0, 0); + set_idt(1, 0); + set_idt(2, 0); + set_idt(3, 3); + set_idt(4, 3); + set_idt(5, 0); + set_idt(6, 0); + set_idt(7, 0); + set_idt(8, 0); + set_idt(9, 0); + set_idt(10, 0); + set_idt(11, 0); + set_idt(12, 0); + set_idt(13, 0); + set_idt(14, 0); + set_idt(15, 0); + set_idt(16, 0); + set_idt(17, 0); + set_idt(18, 0); + set_idt(19, 0); + set_idt(0x80, 3); + + /* linux segment setup */ + { + uint64_t *gdt_table; + env->gdt.base =3D target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENT= RIES, + PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + env->gdt.limit =3D sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; + gdt_table =3D g2h(env->gdt.base); +#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_FS, __USER_DS); + cpu_x86_load_seg(env, R_GS, __USER_DS); + /* This hack makes Wine work... */ + env->segs[R_FS].selector =3D 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 } diff --git a/linux-user/main.c b/linux-user/main.c index 09045f877c..5271473d47 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -149,238 +149,6 @@ void fork_end(int child) } } =20 -#ifdef TARGET_I386 -/***********************************************************/ -/* CPUX86 core interface */ - -uint64_t cpu_get_tsc(CPUX86State *env) -{ - return cpu_get_host_ticks(); -} - -static void write_dt(void *ptr, unsigned long addr, unsigned long limit, - int flags) -{ - unsigned int e1, e2; - uint32_t *p; - e1 =3D (addr << 16) | (limit & 0xffff); - e2 =3D ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f00= 00); - e2 |=3D flags; - p =3D ptr; - p[0] =3D tswap32(e1); - p[1] =3D tswap32(e2); -} - -static uint64_t *idt_table; -#ifdef TARGET_X86_64 -static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, - uint64_t addr, unsigned int sel) -{ - uint32_t *p, e1, e2; - e1 =3D (addr & 0xffff) | (sel << 16); - e2 =3D (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); - p =3D ptr; - p[0] =3D tswap32(e1); - p[1] =3D tswap32(e2); - p[2] =3D tswap32(addr >> 32); - p[3] =3D 0; -} -/* 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 -static void set_gate(void *ptr, unsigned int type, unsigned int dpl, - uint32_t addr, unsigned int sel) -{ - uint32_t *p, e1, e2; - e1 =3D (addr & 0xffff) | (sel << 16); - e2 =3D (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); - p =3D ptr; - p[0] =3D tswap32(e1); - p[1] =3D 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) -{ - CPUState *cs =3D CPU(x86_env_get_cpu(env)); - int trapnr; - abi_ulong pc; - abi_ulong ret; - target_siginfo_t info; - - for(;;) { - cpu_exec_start(cs); - trapnr =3D cpu_exec(cs); - cpu_exec_end(cs); - process_queued_cpu_work(cs); - - switch(trapnr) { - case 0x80: - /* linux syscall from int $0x80 */ - ret =3D do_syscall(env, - env->regs[R_EAX], - env->regs[R_EBX], - env->regs[R_ECX], - env->regs[R_EDX], - env->regs[R_ESI], - env->regs[R_EDI], - env->regs[R_EBP], - 0, 0); - if (ret =3D=3D -TARGET_ERESTARTSYS) { - env->eip -=3D 2; - } else if (ret !=3D -TARGET_QEMU_ESIGRETURN) { - env->regs[R_EAX] =3D ret; - } - break; -#ifndef TARGET_ABI32 - case EXCP_SYSCALL: - /* linux syscall from syscall instruction */ - ret =3D 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], - 0, 0); - if (ret =3D=3D -TARGET_ERESTARTSYS) { - env->eip -=3D 2; - } else if (ret !=3D -TARGET_QEMU_ESIGRETURN) { - env->regs[R_EAX] =3D ret; - } - break; -#endif - case EXCP0B_NOSEG: - case EXCP0C_STACK: - info.si_signo =3D TARGET_SIGBUS; - info.si_errno =3D 0; - info.si_code =3D TARGET_SI_KERNEL; - info._sifields._sigfault._addr =3D 0; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case EXCP0D_GPF: - /* XXX: potential problem if ABI32 */ -#ifndef TARGET_X86_64 - if (env->eflags & VM_MASK) { - handle_vm86_fault(env); - } else -#endif - { - info.si_signo =3D TARGET_SIGSEGV; - info.si_errno =3D 0; - info.si_code =3D TARGET_SI_KERNEL; - info._sifields._sigfault._addr =3D 0; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } - break; - case EXCP0E_PAGE: - info.si_signo =3D TARGET_SIGSEGV; - info.si_errno =3D 0; - if (!(env->error_code & 1)) - info.si_code =3D TARGET_SEGV_MAPERR; - else - info.si_code =3D TARGET_SEGV_ACCERR; - info._sifields._sigfault._addr =3D env->cr[2]; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case EXCP00_DIVZ: -#ifndef TARGET_X86_64 - if (env->eflags & VM_MASK) { - handle_vm86_trap(env, trapnr); - } else -#endif - { - /* division by zero */ - info.si_signo =3D TARGET_SIGFPE; - info.si_errno =3D 0; - info.si_code =3D TARGET_FPE_INTDIV; - info._sifields._sigfault._addr =3D env->eip; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } - break; - case EXCP01_DB: - case EXCP03_INT3: -#ifndef TARGET_X86_64 - if (env->eflags & VM_MASK) { - handle_vm86_trap(env, trapnr); - } else -#endif - { - info.si_signo =3D TARGET_SIGTRAP; - info.si_errno =3D 0; - if (trapnr =3D=3D EXCP01_DB) { - info.si_code =3D TARGET_TRAP_BRKPT; - info._sifields._sigfault._addr =3D env->eip; - } else { - info.si_code =3D TARGET_SI_KERNEL; - info._sifields._sigfault._addr =3D 0; - } - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } - break; - case EXCP04_INTO: - case EXCP05_BOUND: -#ifndef TARGET_X86_64 - if (env->eflags & VM_MASK) { - handle_vm86_trap(env, trapnr); - } else -#endif - { - info.si_signo =3D TARGET_SIGSEGV; - info.si_errno =3D 0; - info.si_code =3D TARGET_SI_KERNEL; - info._sifields._sigfault._addr =3D 0; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } - break; - case EXCP06_ILLOP: - info.si_signo =3D TARGET_SIGILL; - info.si_errno =3D 0; - info.si_code =3D TARGET_ILL_ILLOPN; - info._sifields._sigfault._addr =3D env->eip; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case EXCP_INTERRUPT: - /* just indicate that signals should be handled asap */ - break; - case EXCP_DEBUG: - { - int sig; - - sig =3D gdb_handlesig(cs, TARGET_SIGTRAP); - if (sig) - { - info.si_signo =3D sig; - info.si_errno =3D 0; - info.si_code =3D TARGET_TRAP_BRKPT; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } - } - break; - case EXCP_ATOMIC: - cpu_exec_step_atomic(cs); - break; - default: - pc =3D env->segs[R_CS].base + env->eip; - EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - = aborting\n", - (long)pc, trapnr); - abort(); - } - process_pending_signals(env); - } -} -#endif - #ifdef TARGET_ARM =20 #define get_user_code_u32(x, gaddr, env) \ @@ -4727,121 +4495,7 @@ int main(int argc, char **argv, char **envp) =20 target_cpu_copy_regs(env, regs); =20 -#if defined(TARGET_I386) - env->cr[0] =3D CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; - env->hflags |=3D HF_PE_MASK | HF_CPL_MASK; - if (env->features[FEAT_1_EDX] & CPUID_SSE) { - env->cr[4] |=3D CR4_OSFXSR_MASK; - env->hflags |=3D HF_OSFXSR_MASK; - } -#ifndef TARGET_ABI32 - /* enable 64 bit mode if possible */ - if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) { - fprintf(stderr, "The selected x86 CPU does not support 64 bit mode= \n"); - exit(EXIT_FAILURE); - } - env->cr[4] |=3D CR4_PAE_MASK; - env->efer |=3D MSR_EFER_LMA | MSR_EFER_LME; - env->hflags |=3D HF_LMA_MASK; -#endif - - /* flags setup : we activate the IRQs by default as in user mode */ - env->eflags |=3D IF_MASK; - - /* linux register setup */ -#ifndef TARGET_ABI32 - env->regs[R_EAX] =3D regs->rax; - env->regs[R_EBX] =3D regs->rbx; - env->regs[R_ECX] =3D regs->rcx; - env->regs[R_EDX] =3D regs->rdx; - env->regs[R_ESI] =3D regs->rsi; - env->regs[R_EDI] =3D regs->rdi; - env->regs[R_EBP] =3D regs->rbp; - env->regs[R_ESP] =3D regs->rsp; - env->eip =3D regs->rip; -#else - env->regs[R_EAX] =3D regs->eax; - env->regs[R_EBX] =3D regs->ebx; - env->regs[R_ECX] =3D regs->ecx; - env->regs[R_EDX] =3D regs->edx; - env->regs[R_ESI] =3D regs->esi; - env->regs[R_EDI] =3D regs->edi; - env->regs[R_EBP] =3D regs->ebp; - env->regs[R_ESP] =3D regs->esp; - env->eip =3D regs->eip; -#endif - - /* linux interrupt setup */ -#ifndef TARGET_ABI32 - env->idt.limit =3D 511; -#else - env->idt.limit =3D 255; -#endif - env->idt.base =3D target_mmap(0, sizeof(uint64_t) * (env->idt.limit + = 1), - PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - idt_table =3D g2h(env->idt.base); - set_idt(0, 0); - set_idt(1, 0); - set_idt(2, 0); - set_idt(3, 3); - set_idt(4, 3); - set_idt(5, 0); - set_idt(6, 0); - set_idt(7, 0); - set_idt(8, 0); - set_idt(9, 0); - set_idt(10, 0); - set_idt(11, 0); - set_idt(12, 0); - set_idt(13, 0); - set_idt(14, 0); - set_idt(15, 0); - set_idt(16, 0); - set_idt(17, 0); - set_idt(18, 0); - set_idt(19, 0); - set_idt(0x80, 3); - - /* linux segment setup */ - { - uint64_t *gdt_table; - env->gdt.base =3D target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENT= RIES, - PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - env->gdt.limit =3D sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; - gdt_table =3D g2h(env->gdt.base); -#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_FS, __USER_DS); - cpu_x86_load_seg(env, R_GS, __USER_DS); - /* This hack makes Wine work... */ - env->segs[R_FS].selector =3D 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_AARCH64) +#if defined(TARGET_AARCH64) { int i; =20 diff --git a/linux-user/x86_64/cpu_loop.c b/linux-user/x86_64/cpu_loop.c index b7700a5561..8b5af8ea1f 100644 --- a/linux-user/x86_64/cpu_loop.c +++ b/linux-user/x86_64/cpu_loop.c @@ -17,10 +17,4 @@ * along with this program; if not, see . */ =20 -#include "qemu/osdep.h" -#include "qemu.h" -#include "cpu_loop-common.h" - -void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) -{ -} +#include "../i386/cpu_loop.c" --=20 2.14.3