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

📄 cpu-exec.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#else#error unsupported target CPU#endif    env->exception_index = -1;    /* prepare setjmp context for exception handling */    for(;;) {        if (setjmp(env->jmp_env) == 0) {            env->current_tb = NULL;            /* if an exception is pending, we execute it here */            if (env->exception_index >= 0) {                if (env->exception_index >= EXCP_INTERRUPT) {                    /* exit request from the cpu execution loop */                    ret = env->exception_index;                    break;                } else if (env->user_mode_only) {                    /* if user mode only, we simulate a fake exception                       which will be hanlded outside the cpu execution                       loop */#if defined(TARGET_I386)                    do_interrupt_user(env->exception_index,                                       env->exception_is_int,                                       env->error_code,                                       env->exception_next_eip);#endif                    ret = env->exception_index;                    break;                } else {#if defined(TARGET_I386)                    /* simulate a real cpu exception. On i386, it can                       trigger new exceptions, but we do not handle                       double or triple faults yet. */                    do_interrupt(env->exception_index,                                  env->exception_is_int,                                  env->error_code,                                  env->exception_next_eip, 0);#elif defined(TARGET_PPC)                    do_interrupt(env);#elif defined(TARGET_MIPS)                    do_interrupt(env);#elif defined(TARGET_SPARC)                    do_interrupt(env->exception_index);#elif defined(TARGET_ARM)                    do_interrupt(env);#elif defined(TARGET_SH4)		    do_interrupt(env);#endif                }                env->exception_index = -1;            } #ifdef USE_KQEMU            if (kqemu_is_ok(env) && env->interrupt_request == 0) {                int ret;                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);                ret = kqemu_cpu_exec(env);                /* put eflags in CPU temporary format */                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);                DF = 1 - (2 * ((env->eflags >> 10) & 1));                CC_OP = CC_OP_EFLAGS;                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);                if (ret == 1) {                    /* exception */                    longjmp(env->jmp_env, 1);                } else if (ret == 2) {                    /* softmmu execution needed */                } else {                    if (env->interrupt_request != 0) {                        /* hardware interrupt will be executed just after */                    } else {                        /* otherwise, we restart */                        longjmp(env->jmp_env, 1);                    }                }            }#endif            T0 = 0; /* force lookup of first TB */            for(;;) {#ifdef __sparc__                /* g1 can be modified by some libc? functions */                 tmp_T0 = T0;#endif	                    interrupt_request = env->interrupt_request;                if (__builtin_expect(interrupt_request, 0)) {#if defined(TARGET_I386)                    /* if hardware interrupt pending, we execute it */                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&                        (env->eflags & IF_MASK) &&                         !(env->hflags & HF_INHIBIT_IRQ_MASK)) {                        int intno;                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;                        intno = cpu_get_pic_interrupt(env);                        if (loglevel & CPU_LOG_TB_IN_ASM) {                            fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);                        }                        do_interrupt(intno, 0, 0, 0, 1);                        /* ensure that no TB jump will be modified as                           the program flow was changed */#ifdef __sparc__                        tmp_T0 = 0;#else                        T0 = 0;#endif                    }#elif defined(TARGET_PPC)#if 0                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {                        cpu_ppc_reset(env);                    }#endif                    if (msr_ee != 0) {                        if ((interrupt_request & CPU_INTERRUPT_HARD)) {			    /* Raise it */			    env->exception_index = EXCP_EXTERNAL;			    env->error_code = 0;                            do_interrupt(env);                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;#ifdef __sparc__                            tmp_T0 = 0;#else                            T0 = 0;#endif                        } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {                            /* Raise it */                            env->exception_index = EXCP_DECR;                            env->error_code = 0;                            do_interrupt(env);                            env->interrupt_request &= ~CPU_INTERRUPT_TIMER;#ifdef __sparc__                            tmp_T0 = 0;#else                            T0 = 0;#endif                        }                    }#elif defined(TARGET_MIPS)                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&                        (env->CP0_Status & (1 << CP0St_IE)) &&                        (env->CP0_Status & env->CP0_Cause & 0x0000FF00) &&                        !(env->hflags & MIPS_HFLAG_EXL) &&                        !(env->hflags & MIPS_HFLAG_ERL) &&                        !(env->hflags & MIPS_HFLAG_DM)) {                        /* Raise it */                        env->exception_index = EXCP_EXT_INTERRUPT;                        env->error_code = 0;                        do_interrupt(env);                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;#ifdef __sparc__                        tmp_T0 = 0;#else                        T0 = 0;#endif                    }#elif defined(TARGET_SPARC)                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&			(env->psret != 0)) {			int pil = env->interrupt_index & 15;			int type = env->interrupt_index & 0xf0;			if (((type == TT_EXTINT) &&			     (pil == 15 || pil > env->psrpil)) ||			    type != TT_EXTINT) {			    env->interrupt_request &= ~CPU_INTERRUPT_HARD;			    do_interrupt(env->interrupt_index);			    env->interrupt_index = 0;#ifdef __sparc__                            tmp_T0 = 0;#else                            T0 = 0;#endif			}		    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {			//do_interrupt(0, 0, 0, 0, 0);			env->interrupt_request &= ~CPU_INTERRUPT_TIMER;		    } else if (interrupt_request & CPU_INTERRUPT_HALT) {                        env1->halted = 1;                        return EXCP_HALTED;                    }#elif defined(TARGET_ARM)                    if (interrupt_request & CPU_INTERRUPT_FIQ                        && !(env->uncached_cpsr & CPSR_F)) {                        env->exception_index = EXCP_FIQ;                        do_interrupt(env);                    }                    if (interrupt_request & CPU_INTERRUPT_HARD                        && !(env->uncached_cpsr & CPSR_I)) {                        env->exception_index = EXCP_IRQ;                        do_interrupt(env);                    }#elif defined(TARGET_SH4)		    /* XXXXX */#endif                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;                        /* ensure that no TB jump will be modified as                           the program flow was changed */#ifdef __sparc__                        tmp_T0 = 0;#else                        T0 = 0;#endif                    }                    if (interrupt_request & CPU_INTERRUPT_EXIT) {                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;                        env->exception_index = EXCP_INTERRUPT;                        cpu_loop_exit();                    }                }#ifdef DEBUG_EXEC                if ((loglevel & CPU_LOG_TB_CPU)) {#if defined(TARGET_I386)                    /* restore flags in standard format */#ifdef reg_EAX                    env->regs[R_EAX] = EAX;#endif#ifdef reg_EBX                    env->regs[R_EBX] = EBX;#endif#ifdef reg_ECX                    env->regs[R_ECX] = ECX;#endif#ifdef reg_EDX                    env->regs[R_EDX] = EDX;#endif#ifdef reg_ESI                    env->regs[R_ESI] = ESI;#endif#ifdef reg_EDI                    env->regs[R_EDI] = EDI;#endif#ifdef reg_EBP                    env->regs[R_EBP] = EBP;#endif#ifdef reg_ESP                    env->regs[R_ESP] = ESP;#endif                    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);                    cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);                    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);#elif defined(TARGET_ARM)                    cpu_dump_state(env, logfile, fprintf, 0);#elif defined(TARGET_SPARC)		    REGWPTR = env->regbase + (env->cwp * 16);		    env->regwptr = REGWPTR;                    cpu_dump_state(env, logfile, fprintf, 0);#elif defined(TARGET_PPC)                    cpu_dump_state(env, logfile, fprintf, 0);#elif defined(TARGET_MIPS)                    cpu_dump_state(env, logfile, fprintf, 0);#elif defined(TARGET_SH4)		    cpu_dump_state(env, logfile, fprintf, 0);#else#error unsupported target CPU #endif                }#endif                tb = tb_find_fast();#ifdef DEBUG_EXEC                if ((loglevel & CPU_LOG_EXEC)) {                    fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",                            (long)tb->tc_ptr, tb->pc,                            lookup_symbol(tb->pc));                }#endif#ifdef __sparc__                T0 = tmp_T0;#endif	                    /* see if we can patch the calling TB. When the TB                   spans two pages, we cannot safely do a direct                   jump. */                {                    if (T0 != 0 &&#if USE_KQEMU                        (env->kqemu_enabled != 2) &&#endif                        tb->page_addr[1] == -1#if defined(TARGET_I386) && defined(USE_CODE_COPY)                    && (tb->cflags & CF_CODE_COPY) ==                     (((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)#endif                    ) {                    spin_lock(&tb_lock);                    tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);#if defined(USE_CODE_COPY)                    /* propagates the FP use info */                    ((TranslationBlock *)(T0 & ~3))->cflags |=                         (tb->cflags & CF_FP_USED);#endif                    spin_unlock(&tb_lock);                }                }                tc_ptr = tb->tc_ptr;                env->current_tb = tb;                /* execute the generated code */                gen_func = (void *)tc_ptr;#if defined(__sparc__)                __asm__ __volatile__("call	%0\n\t"                                     "mov	%%o7,%%i0"                                     : /* no outputs */                                     : "r" (gen_func)                                      : "i0", "i1", "i2", "i3", "i4", "i5");#elif defined(__arm__)                asm volatile ("mov pc, %0\n\t"                              ".global exec_loop\n\t"                              "exec_loop:\n\t"                              : /* no outputs */                              : "r" (gen_func)                              : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");#elif defined(TARGET_I386) && defined(USE_CODE_COPY){    if (!(tb->cflags & CF_CODE_COPY)) {        if ((tb->cflags & CF_FP_USED) && env->native_fp_regs) {            save_native_fp_state(env);        }        gen_func();    } else {        if ((tb->cflags & CF_FP_USED) && !env->native_fp_regs) {            restore_native_fp_state(env);        }        /* we work with native eflags */        CC_SRC = cc_table[CC_OP].compute_all();        CC_OP = CC_OP_EFLAGS;        asm(".globl exec_loop\n"            "\n"            "debug1:\n"            "    pushl %%ebp\n"            "    fs movl %10, %9\n"            "    fs movl %11, %%eax\n"            "    andl $0x400, %%eax\n"            "    fs orl %8, %%eax\n"            "    pushl %%eax\n"            "    popf\n"            "    fs movl %%esp, %12\n"            "    fs movl %0, %%eax\n"            "    fs movl %1, %%ecx\n"            "    fs movl %2, %%edx\n"            "    fs movl %3, %%ebx\n"            "    fs movl %4, %%esp\n"            "    fs movl %5, %%ebp\n"            "    fs movl %6, %%esi\n"            "    fs movl %7, %%edi\n"            "    fs jmp *%9\n"            "exec_loop:\n"            "    fs movl %%esp, %4\n"            "    fs movl %12, %%esp\n"            "    fs movl %%eax, %0\n"            "    fs movl %%ecx, %1\n"            "    fs movl %%edx, %2\n"            "    fs movl %%ebx, %3\n"            "    fs movl %%ebp, %5\n"            "    fs movl %%esi, %6\n"            "    fs movl %%edi, %7\n"            "    pushf\n"            "    popl %%eax\n"            "    movl %%eax, %%ecx\n"            "    andl $0x400, %%ecx\n"            "    shrl $9, %%ecx\n"            "    andl $0x8d5, %%eax\n"            "    fs movl %%eax, %8\n"            "    movl $1, %%eax\n"            "    subl %%ecx, %%eax\n"            "    fs movl %%eax, %11\n"            "    fs movl %9, %%ebx\n" /* get T0 value */            "    popl %%ebp\n"            :            : "m" (*(uint8_t *)offsetof(CPUState, regs[0])),            "m" (*(uint8_t *)offsetof(CPUState, regs[1])),            "m" (*(uint8_t *)offsetof(CPUState, regs[2])),            "m" (*(uint8_t *)offsetof(CPUState, regs[3])),            "m" (*(uint8_t *)offsetof(CPUState, regs[4])),            "m" (*(uint8_t *)offsetof(CPUState, regs[5])),

⌨️ 快捷键说明

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