⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu-exec.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            "m" (*(uint8_t *)offsetof(CPUState, regs[6])),            "m" (*(uint8_t *)offsetof(CPUState, regs[7])),            "m" (*(uint8_t *)offsetof(CPUState, cc_src)),            "m" (*(uint8_t *)offsetof(CPUState, tmp0)),            "a" (gen_func),            "m" (*(uint8_t *)offsetof(CPUState, df)),            "m" (*(uint8_t *)offsetof(CPUState, saved_esp))            : "%ecx", "%edx"            );    }}#elif defined(__ia64)		struct fptr {			void *ip;			void *gp;		} fp;		fp.ip = tc_ptr;		fp.gp = code_gen_buffer + 2 * (1 << 20);		(*(void (*)(void)) &fp)();#else                gen_func();#endif                env->current_tb = NULL;                /* reset soft MMU for next block (it can currently                   only be set by a memory fault) */#if defined(TARGET_I386) && !defined(CONFIG_SOFTMMU)                if (env->hflags & HF_SOFTMMU_MASK) {                    env->hflags &= ~HF_SOFTMMU_MASK;                    /* do not allow linking to another block */                    T0 = 0;                }#endif#if defined(USE_KQEMU)#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)                if (kqemu_is_ok(env) &&                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {                    cpu_loop_exit();                }#endif            }        } else {            env_to_regs();        }    } /* for(;;) */#if defined(TARGET_I386)#if defined(USE_CODE_COPY)    if (env->native_fp_regs) {        save_native_fp_state(env);    }#endif    /* restore flags in standard format */    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);    /* restore global registers */#ifdef reg_EAX    EAX = saved_EAX;#endif#ifdef reg_ECX    ECX = saved_ECX;#endif#ifdef reg_EDX    EDX = saved_EDX;#endif#ifdef reg_EBX    EBX = saved_EBX;#endif#ifdef reg_ESP    ESP = saved_ESP;#endif#ifdef reg_EBP    EBP = saved_EBP;#endif#ifdef reg_ESI    ESI = saved_ESI;#endif#ifdef reg_EDI    EDI = saved_EDI;#endif#elif defined(TARGET_ARM)    /* XXX: Save/restore host fpu exception state?.  */#elif defined(TARGET_SPARC)#if defined(reg_REGWPTR)    REGWPTR = saved_regwptr;#endif#elif defined(TARGET_PPC)#elif defined(TARGET_MIPS)#elif defined(TARGET_SH4)    /* XXXXX */#else#error unsupported target CPU#endif#ifdef __sparc__    asm volatile ("mov %0, %%i7" : : "r" (saved_i7));#endif    T0 = saved_T0;    T1 = saved_T1;#if defined(reg_T2)    T2 = saved_T2;#endif    env = saved_env;    /* fail safe : never use cpu_single_env outside cpu_exec() */    cpu_single_env = NULL;     return ret;}/* must only be called from the generated code as an exception can be   generated */void tb_invalidate_page_range(target_ulong start, target_ulong end){    /* XXX: cannot enable it yet because it yields to MMU exception       where NIP != read address on PowerPC */#if 0    target_ulong phys_addr;    phys_addr = get_phys_addr_code(env, start);    tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);#endif}#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector){    CPUX86State *saved_env;    saved_env = env;    env = s;    if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {        selector &= 0xffff;        cpu_x86_load_seg_cache(env, seg_reg, selector,                                (selector << 4), 0xffff, 0);    } else {        load_seg(seg_reg, selector);    }    env = saved_env;}void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32){    CPUX86State *saved_env;    saved_env = env;    env = s;        helper_fsave((target_ulong)ptr, data32);    env = saved_env;}void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32){    CPUX86State *saved_env;    saved_env = env;    env = s;        helper_frstor((target_ulong)ptr, data32);    env = saved_env;}#endif /* TARGET_I386 */#if !defined(CONFIG_SOFTMMU)#if defined(TARGET_I386)/* 'pc' is the host PC at which the exception was raised. 'address' is   the effective address of the memory exception. 'is_write' is 1 if a   write caused the exception and otherwise 0'. 'old_set' is the   signal set which should be restored */static inline int handle_cpu_signal(unsigned long pc, unsigned long address,                                    int is_write, sigset_t *old_set,                                     void *puc){    TranslationBlock *tb;    int ret;    if (cpu_single_env)        env = cpu_single_env; /* XXX: find a correct solution for multithread */#if defined(DEBUG_SIGNAL)    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",                 pc, address, is_write, *(unsigned long *)old_set);#endif    /* XXX: locking issue */    if (is_write && page_unprotect(h2g(address), pc, puc)) {        return 1;    }    /* see if it is an MMU fault */    ret = cpu_x86_handle_mmu_fault(env, address, is_write,                                    ((env->hflags & HF_CPL_MASK) == 3), 0);    if (ret < 0)        return 0; /* not an MMU fault */    if (ret == 0)        return 1; /* the MMU fault was handled without causing real CPU fault */    /* now we have a real cpu fault */    tb = tb_find_pc(pc);    if (tb) {        /* the PC is inside the translated code. It means that we have           a virtual CPU fault */        cpu_restore_state(tb, env, pc, puc);    }    if (ret == 1) {#if 0        printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",                env->eip, env->cr[2], env->error_code);#endif        /* we restore the process signal mask as the sigreturn should           do it (XXX: use sigsetjmp) */        sigprocmask(SIG_SETMASK, old_set, NULL);        raise_exception_err(env->exception_index, env->error_code);    } else {        /* activate soft MMU for this block */        env->hflags |= HF_SOFTMMU_MASK;        cpu_resume_from_signal(env, puc);    }    /* never comes here */    return 1;}#elif defined(TARGET_ARM)static inline int handle_cpu_signal(unsigned long pc, unsigned long address,                                    int is_write, sigset_t *old_set,                                    void *puc){    TranslationBlock *tb;    int ret;    if (cpu_single_env)        env = cpu_single_env; /* XXX: find a correct solution for multithread */#if defined(DEBUG_SIGNAL)    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",            pc, address, is_write, *(unsigned long *)old_set);#endif    /* XXX: locking issue */    if (is_write && page_unprotect(h2g(address), pc, puc)) {        return 1;    }    /* see if it is an MMU fault */    ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);    if (ret < 0)        return 0; /* not an MMU fault */    if (ret == 0)        return 1; /* the MMU fault was handled without causing real CPU fault */    /* now we have a real cpu fault */    tb = tb_find_pc(pc);    if (tb) {        /* the PC is inside the translated code. It means that we have           a virtual CPU fault */        cpu_restore_state(tb, env, pc, puc);    }    /* we restore the process signal mask as the sigreturn should       do it (XXX: use sigsetjmp) */    sigprocmask(SIG_SETMASK, old_set, NULL);    cpu_loop_exit();}#elif defined(TARGET_SPARC)static inline int handle_cpu_signal(unsigned long pc, unsigned long address,                                    int is_write, sigset_t *old_set,                                    void *puc){    TranslationBlock *tb;    int ret;    if (cpu_single_env)        env = cpu_single_env; /* XXX: find a correct solution for multithread */#if defined(DEBUG_SIGNAL)    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",            pc, address, is_write, *(unsigned long *)old_set);#endif    /* XXX: locking issue */    if (is_write && page_unprotect(h2g(address), pc, puc)) {        return 1;    }    /* see if it is an MMU fault */    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);    if (ret < 0)        return 0; /* not an MMU fault */    if (ret == 0)        return 1; /* the MMU fault was handled without causing real CPU fault */    /* now we have a real cpu fault */    tb = tb_find_pc(pc);    if (tb) {        /* the PC is inside the translated code. It means that we have           a virtual CPU fault */        cpu_restore_state(tb, env, pc, puc);    }    /* we restore the process signal mask as the sigreturn should       do it (XXX: use sigsetjmp) */    sigprocmask(SIG_SETMASK, old_set, NULL);    cpu_loop_exit();}#elif defined (TARGET_PPC)static inline int handle_cpu_signal(unsigned long pc, unsigned long address,                                    int is_write, sigset_t *old_set,                                    void *puc){    TranslationBlock *tb;    int ret;        if (cpu_single_env)        env = cpu_single_env; /* XXX: find a correct solution for multithread */#if defined(DEBUG_SIGNAL)    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",            pc, address, is_write, *(unsigned long *)old_set);#endif    /* XXX: locking issue */    if (is_write && page_unprotect(h2g(address), pc, puc)) {        return 1;    }    /* see if it is an MMU fault */    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);    if (ret < 0)        return 0; /* not an MMU fault */    if (ret == 0)        return 1; /* the MMU fault was handled without causing real CPU fault */    /* now we have a real cpu fault */    tb = tb_find_pc(pc);    if (tb) {        /* the PC is inside the translated code. It means that we have           a virtual CPU fault */        cpu_restore_state(tb, env, pc, puc);    }    if (ret == 1) {#if 0        printf("PF exception: NIP=0x%08x error=0x%x %p\n",                env->nip, env->error_code, tb);#endif    /* we restore the process signal mask as the sigreturn should       do it (XXX: use sigsetjmp) */        sigprocmask(SIG_SETMASK, old_set, NULL);        do_raise_exception_err(env->exception_index, env->error_code);    } else {        /* activate soft MMU for this block */        cpu_resume_from_signal(env, puc);    }    /* never comes here */    return 1;}#elif defined (TARGET_MIPS)static inline int handle_cpu_signal(unsigned long pc, unsigned long address,                                    int is_write, sigset_t *old_set,                                    void *puc){    TranslationBlock *tb;    int ret;        if (cpu_single_env)        env = cpu_single_env; /* XXX: find a correct solution for multithread */#if defined(DEBUG_SIGNAL)    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",            pc, address, is_write, *(unsigned long *)old_set);#endif    /* XXX: locking issue */    if (is_write && page_unprotect(h2g(address), pc, puc)) {        return 1;    }    /* see if it is an MMU fault */    ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);    if (ret < 0)        return 0; /* not an MMU fault */    if (ret == 0)        return 1; /* the MMU fault was handled without causing real CPU fault */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -