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

📄 main.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                queue_signal(info.si_signo, &info);            }            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;        default:        error:            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",                     trapnr);            cpu_dump_state(env, stderr, fprintf, 0);            abort();        }        process_pending_signals(env);    }}#endif#ifdef TARGET_SPARC//#define DEBUG_WIN/* WARNING: dealing with register windows _is_ complicated. More info   can be found at http://www.sics.se/~psm/sparcstack.html */static inline int get_reg_index(CPUSPARCState *env, int cwp, int index){    index = (index + cwp * 16) & (16 * NWINDOWS - 1);    /* wrap handling : if cwp is on the last window, then we use the       registers 'after' the end */    if (index < 8 && env->cwp == (NWINDOWS - 1))        index += (16 * NWINDOWS);    return index;}/* save the register window 'cwp1' */static inline void save_window_offset(CPUSPARCState *env, int cwp1){    unsigned int i;    target_ulong sp_ptr;        sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];#if defined(DEBUG_WIN)    printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",            (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);    }}static void save_window(CPUSPARCState *env){    unsigned int new_wim;    new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &        ((1LL << NWINDOWS) - 1);    save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));    env->wim = new_wim;}static void restore_window(CPUSPARCState *env){    unsigned int new_wim, i, cwp1;    target_ulong sp_ptr;        new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &        ((1LL << NWINDOWS) - 1);        /* restore the invalid window */    cwp1 = (env->cwp + 1) & (NWINDOWS - 1);    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];#if defined(DEBUG_WIN)    printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",            (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);    }    env->wim = new_wim;}static void flush_windows(CPUSPARCState *env){    int offset, cwp1;    offset = 1;    for(;;) {        /* if restore would invoke restore_window(), then we can stop */        cwp1 = (env->cwp + offset) & (NWINDOWS - 1);        if (env->wim & (1 << cwp1))            break;        save_window_offset(env, cwp1);        offset++;    }    /* set wim so that restore will reload the registers */    cwp1 = (env->cwp + 1) & (NWINDOWS - 1);    env->wim = 1 << cwp1;#if defined(DEBUG_WIN)    printf("flush_windows: nb=%d\n", offset - 1);#endif}void cpu_loop (CPUSPARCState *env){    int trapnr, ret;    target_siginfo_t info;        while (1) {        trapnr = cpu_sparc_exec (env);                switch (trapnr) {        case 0x88:         case 0x90:            ret = do_syscall (env, env->gregs[1],                              env->regwptr[0], env->regwptr[1],                               env->regwptr[2], env->regwptr[3],                               env->regwptr[4], env->regwptr[5]);            if ((unsigned int)ret >= (unsigned int)(-515)) {                env->psr |= PSR_CARRY;                ret = -ret;            } else {                env->psr &= ~PSR_CARRY;            }            env->regwptr[0] = ret;            /* next instruction */            env->pc = env->npc;            env->npc = env->npc + 4;            break;        case 0x83: /* flush windows */            flush_windows(env);            /* next instruction */            env->pc = env->npc;            env->npc = env->npc + 4;            break;#ifndef TARGET_SPARC64        case TT_WIN_OVF: /* window overflow */            save_window(env);            break;        case TT_WIN_UNF: /* window underflow */            restore_window(env);            break;        case TT_TFAULT:        case TT_DFAULT:            {                info.si_signo = SIGSEGV;                info.si_errno = 0;                /* XXX: check env->error_code */                info.si_code = TARGET_SEGV_MAPERR;                info._sifields._sigfault._addr = env->mmuregs[4];                queue_signal(info.si_signo, &info);            }            break;#else	    // XXX#endif	case 0x100: // XXX, why do we get these?	    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;        default:            printf ("Unhandled trap: 0x%x\n", trapnr);            cpu_dump_state(env, stderr, fprintf, 0);            exit (1);        }        process_pending_signals (env);    }}#endif#ifdef TARGET_PPCstatic inline uint64_t cpu_ppc_get_tb (CPUState *env){    /* TO FIX */    return 0;}  uint32_t cpu_ppc_load_tbl (CPUState *env){    return cpu_ppc_get_tb(env) & 0xFFFFFFFF;}  uint32_t cpu_ppc_load_tbu (CPUState *env){    return cpu_ppc_get_tb(env) >> 32;}  static void cpu_ppc_store_tb (CPUState *env, uint64_t value){    /* TO FIX */}void cpu_ppc_store_tbu (CPUState *env, uint32_t value){    cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));} void cpu_ppc_store_tbl (CPUState *env, uint32_t value){    cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);}  uint32_t cpu_ppc_load_decr (CPUState *env){    /* TO FIX */    return -1;} void cpu_ppc_store_decr (CPUState *env, uint32_t value){    /* TO FIX */} void cpu_loop(CPUPPCState *env){    target_siginfo_t info;    int trapnr;    uint32_t ret;        for(;;) {        trapnr = cpu_ppc_exec(env);        if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH &&            trapnr != EXCP_TRACE) {            if (loglevel > 0) {                cpu_dump_state(env, logfile, fprintf, 0);            }        }        switch(trapnr) {        case EXCP_NONE:            break;        case EXCP_SYSCALL_USER:            /* system call */            /* WARNING:             * PPC ABI uses overflow flag in cr0 to signal an error             * in syscalls.             */#if 0            printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],                   env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);#endif            env->crf[0] &= ~0x1;            ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],                             env->gpr[5], env->gpr[6], env->gpr[7],                             env->gpr[8]);            if (ret > (uint32_t)(-515)) {                env->crf[0] |= 0x1;                ret = -ret;            }            env->gpr[3] = ret;#if 0            printf("syscall returned 0x%08x (%d)\n", ret, ret);#endif            break;        case EXCP_RESET:            /* Should not happen ! */            fprintf(stderr, "RESET asked... Stop emulation\n");            if (loglevel)                fprintf(logfile, "RESET asked... Stop emulation\n");            abort();        case EXCP_MACHINE_CHECK:            fprintf(stderr, "Machine check exeption...  Stop emulation\n");            if (loglevel)                fprintf(logfile, "RESET asked... Stop emulation\n");            info.si_signo = TARGET_SIGBUS;            info.si_errno = 0;            info.si_code = TARGET_BUS_OBJERR;            info._sifields._sigfault._addr = env->nip - 4;            queue_signal(info.si_signo, &info);        case EXCP_DSI:            fprintf(stderr, "Invalid data memory access: 0x%08x\n",                    env->spr[SPR_DAR]);            if (loglevel) {                fprintf(logfile, "Invalid data memory access: 0x%08x\n",                        env->spr[SPR_DAR]);            }            switch (env->error_code & 0xFF000000) {            case 0x40000000:                info.si_signo = TARGET_SIGSEGV;                info.si_errno = 0;                info.si_code = TARGET_SEGV_MAPERR;                break;            case 0x04000000:                info.si_signo = TARGET_SIGILL;                info.si_errno = 0;                info.si_code = TARGET_ILL_ILLADR;                break;            case 0x08000000:                info.si_signo = TARGET_SIGSEGV;                info.si_errno = 0;                info.si_code = TARGET_SEGV_ACCERR;                break;            default:                /* Let's send a regular segfault... */                fprintf(stderr, "Invalid segfault errno (%02x)\n",                        env->error_code);                if (loglevel) {                    fprintf(logfile, "Invalid segfault errno (%02x)\n",                            env->error_code);                }                info.si_signo = TARGET_SIGSEGV;                info.si_errno = 0;                info.si_code = TARGET_SEGV_MAPERR;                break;            }            info._sifields._sigfault._addr = env->nip;            queue_signal(info.si_signo, &info);            break;        case EXCP_ISI:            fprintf(stderr, "Invalid instruction fetch\n");            if (loglevel)                fprintf(logfile, "Invalid instruction fetch\n");            switch (env->error_code & 0xFF000000) {            case 0x40000000:                info.si_signo = TARGET_SIGSEGV;            info.si_errno = 0;                info.si_code = TARGET_SEGV_MAPERR;                break;            case 0x10000000:            case 0x08000000:                info.si_signo = TARGET_SIGSEGV;                info.si_errno = 0;                info.si_code = TARGET_SEGV_ACCERR;                break;            default:                /* Let's send a regular segfault... */                fprintf(stderr, "Invalid segfault errno (%02x)\n",                        env->error_code);                if (loglevel) {                    fprintf(logfile, "Invalid segfault errno (%02x)\n",                            env->error_code);                }                info.si_signo = TARGET_SIGSEGV;                info.si_errno = 0;                info.si_code = TARGET_SEGV_MAPERR;                break;            }            info._sifields._sigfault._addr = env->nip - 4;            queue_signal(info.si_signo, &info);            break;        case EXCP_EXTERNAL:            /* Should not happen ! */            fprintf(stderr, "External interruption... Stop emulation\n");            if (loglevel)                fprintf(logfile, "External interruption... Stop emulation\n");            abort();        case EXCP_ALIGN:            fprintf(stderr, "Invalid unaligned memory access\n");            if (loglevel)                fprintf(logfile, "Invalid unaligned memory access\n");            info.si_signo = TARGET_SIGBUS;            info.si_errno = 0;            info.si_code = TARGET_BUS_ADRALN;            info._sifields._sigfault._addr = env->nip - 4;            queue_signal(info.si_signo, &info);            break;        case EXCP_PROGRAM:            switch (env->error_code & ~0xF) {            case EXCP_FP:            fprintf(stderr, "Program exception\n");                if (loglevel)                    fprintf(logfile, "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) {                case EXCP_FP_OX:                    info.si_code = TARGET_FPE_FLTOVF;                    break;                case EXCP_FP_UX:                    info.si_code = TARGET_FPE_FLTUND;                    break;                case EXCP_FP_ZX:                case EXCP_FP_VXZDZ:                    info.si_code = TARGET_FPE_FLTDIV;                    break;                case EXCP_FP_XX:                    info.si_code = TARGET_FPE_FLTRES;                    break;                case EXCP_FP_VXSOFT:                    info.si_code = TARGET_FPE_FLTINV;                    break;                case EXCP_FP_VXNAN:                case EXCP_FP_VXISI:                case EXCP_FP_VXIDI:                case EXCP_FP_VXIMZ:                case EXCP_FP_VXVC:                case EXCP_FP_VXSQRT:                case EXCP_FP_VXCVI:                    info.si_code = TARGET_FPE_FLTSUB;                    break;                default:                    fprintf(stderr, "Unknown floating point exception "                            "(%02x)\n", env->error_code);                    if (loglevel) {                        fprintf(logfile, "Unknown floating point exception "                                "(%02x)\n", env->error_code & 0xF);                    }                }            break;        case EXCP_INVAL:

⌨️ 快捷键说明

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