📄 main.c.svn-base
字号:
} else { /* increment PC */ env->regs[15] += 4; } } break; case EXCP_SWI: case EXCP_BKPT: { env->eabi = 1; /* system call */ if (trapnr == EXCP_BKPT) { if (env->thumb) { /* FIXME - what to do if get_user() fails? */ get_user_u16(insn, env->regs[15]); n = insn & 0xff; env->regs[15] += 2; } else { /* 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) { /* FIXME - what to do if get_user() fails? */ get_user_u16(insn, env->regs[15] - 2); n = insn & 0xff; } else { /* FIXME - what to do if get_user() fails? */ get_user_u32(insn, env->regs[15] - 4); n = insn & 0xffffff; } } if (n == ARM_NR_cacheflush) { arm_cache_flush(env->regs[0], env->regs[1]); } else if (n == ARM_NR_semihosting || n == ARM_NR_thumb_semihosting) { env->regs[0] = do_arm_semihosting (env); } else if (n == 0 || n >= ARM_SYSCALL_BASE || (env->thumb && n == ARM_THUMB_SYSCALL)) { /* linux syscall */ if (env->thumb || n == 0) { n = env->regs[7]; } else { n -= ARM_SYSCALL_BASE; env->eabi = 0; } env->regs[0] = do_syscall(env, n, env->regs[0], env->regs[1], env->regs[2], env->regs[3], env->regs[4], env->regs[5]); } else { goto error; } } break; case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; case EXCP_PREFETCH_ABORT: addr = env->cp15.c6_data; goto do_segv; case EXCP_DATA_ABORT: addr = env->cp15.c6_insn; goto do_segv; do_segv: { info.si_signo = SIGSEGV; info.si_errno = 0; /* XXX: check env->error_code */ info.si_code = TARGET_SEGV_MAPERR; info._sifields._sigfault._addr = addr; 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; abi_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++) { /* 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); }}static void save_window(CPUSPARCState *env){#ifndef TARGET_SPARC64 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;#else save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); env->cansave++; env->canrestore--;#endif}static void restore_window(CPUSPARCState *env){ unsigned int new_wim, i, cwp1; abi_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++) { /* 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 env->canrestore++; if (env->cleanwin < NWINDOWS - 1) env->cleanwin++; env->cansave--;#endif}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) {#ifndef TARGET_SPARC64 case 0x88: case 0x90:#else case 0x110: case 0x16d:#endif 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)) {#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc |= PSR_CARRY;#else env->psr |= PSR_CARRY;#endif ret = -ret; } else {#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc &= ~PSR_CARRY;#else env->psr &= ~PSR_CARRY;#endif } env->regwptr[0] = ret; /* next instruction */ env->pc = env->npc; 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; 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 case TT_SPILL: /* window overflow */ save_window(env); break; case TT_FILL: /* 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; if (trapnr == TT_DFAULT) info._sifields._sigfault._addr = env->dmmuregs[4]; else info._sifields._sigfault._addr = env->tpc[env->tl]; 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 */ 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;}uint32_t cpu_ppc_load_atbl (CPUState *env){ return cpu_ppc_get_tb(env) & 0xFFFFFFFF;}uint32_t cpu_ppc_load_atbu (CPUState *env){ return cpu_ppc_get_tb(env) >> 32;}uint32_t cpu_ppc601_load_rtcu (CPUState *env)__attribute__ (( alias ("cpu_ppc_load_tbu") ));uint32_t cpu_ppc601_load_rtcl (CPUState *env){ return cpu_ppc_load_tbl(env) & 0x3FFFFF80;}/* XXX: to be fixed */int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp){ return -1;}int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val){ return -1;}#define EXCP_DUMP(env, fmt, args...) \do { \ fprintf(stderr, fmt , ##args); \ cpu_dump_state(env, stderr, fprintf, 0); \ if (loglevel != 0) { \ fprintf(logfile, fmt , ##args); \ cpu_dump_state(env, logfile, fprintf, 0); \ } \} while (0)void cpu_loop(CPUPPCState *env){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -