?? main.c
字號:
/* * qemu user main * * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2006 Pierre d'Herbemont * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/syscall.h>#include <sys/mman.h>#include "qemu.h"#define DEBUG_LOGFILE "/tmp/qemu.log"#ifdef __APPLE__#include <crt_externs.h># define environ (*_NSGetEnviron())#endif#include <mach/mach_init.h>#include <mach/vm_map.h>const char *interp_prefix = "";asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so we allocate a bigger stack. Need a better solution, for example by remapping the process stack directly at the right place */unsigned long stack_size = 512 * 1024;void qerror(const char *fmt, ...){ va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); exit(1);}void gemu_log(const char *fmt, ...){ va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);}void cpu_outb(CPUState *env, int addr, int val){ fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);}void cpu_outw(CPUState *env, int addr, int val){ fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);}void cpu_outl(CPUState *env, int addr, int val){ fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);}int cpu_inb(CPUState *env, int addr){ fprintf(stderr, "inb: port=0x%04x\n", addr); return 0;}int cpu_inw(CPUState *env, int addr){ fprintf(stderr, "inw: port=0x%04x\n", addr); return 0;}int cpu_inl(CPUState *env, int addr){ fprintf(stderr, "inl: port=0x%04x\n", addr); return 0;}int cpu_get_pic_interrupt(CPUState *env){ return -1;}#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){ cpu_ppc_load_tbu(env);}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){ int trapnr; uint32_t ret; target_siginfo_t info; for(;;) { trapnr = cpu_ppc_exec(env); switch(trapnr) { case POWERPC_EXCP_NONE: /* Just go on */ break; case POWERPC_EXCP_CRITICAL: /* Critical input */ cpu_abort(env, "Critical interrupt while in user mode. " "Aborting\n"); break; case POWERPC_EXCP_MCHECK: /* Machine check exception */ cpu_abort(env, "Machine check exception while in user mode. " "Aborting\n"); break; case POWERPC_EXCP_DSI: /* Data storage exception */#ifndef DAR/* To deal with multiple qemu header version as host for the darwin-user code */# define DAR SPR_DAR#endif EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n", env->spr[SPR_DAR]); /* Handle this via the gdb */ gdb_handlesig (env, SIGSEGV); info.si_addr = (void*)env->nip; queue_signal(info.si_signo, &info); break; case POWERPC_EXCP_ISI: /* Instruction storage exception */ EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n", env->spr[SPR_DAR]); /* Handle this via the gdb */ gdb_handlesig (env, SIGSEGV); info.si_addr = (void*)(env->nip - 4); queue_signal(info.si_signo, &info); break; case POWERPC_EXCP_EXTERNAL: /* External input */ cpu_abort(env, "External interrupt while in user mode. " "Aborting\n"); break; case POWERPC_EXCP_ALIGN: /* Alignment exception */ EXCP_DUMP(env, "Unaligned memory access\n"); info.si_errno = 0; info.si_code = BUS_ADRALN; info.si_addr = (void*)(env->nip - 4); queue_signal(info.si_signo, &info); break; case POWERPC_EXCP_PROGRAM: /* Program exception */ /* XXX: check this */ switch (env->error_code & ~0xF) { case POWERPC_EXCP_FP: EXCP_DUMP(env, "Floating point program exception\n"); /* Set FX */ info.si_signo = SIGFPE; info.si_errno = 0; switch (env->error_code & 0xF) { case POWERPC_EXCP_FP_OX: info.si_code = FPE_FLTOVF; break; case POWERPC_EXCP_FP_UX: info.si_code = FPE_FLTUND; break; case POWERPC_EXCP_FP_ZX: case POWERPC_EXCP_FP_VXZDZ: info.si_code = FPE_FLTDIV; break; case POWERPC_EXCP_FP_XX: info.si_code = FPE_FLTRES; break; case POWERPC_EXCP_FP_VXSOFT: info.si_code = FPE_FLTINV; break; case POWERPC_EXCP_FP_VXSNAN: case POWERPC_EXCP_FP_VXISI: case POWERPC_EXCP_FP_VXIDI: case POWERPC_EXCP_FP_VXIMZ: case POWERPC_EXCP_FP_VXVC: case POWERPC_EXCP_FP_VXSQRT: case POWERPC_EXCP_FP_VXCVI: info.si_code = FPE_FLTSUB; break; default: EXCP_DUMP(env, "Unknown floating point exception (%02x)\n", env->error_code); break; } break; case POWERPC_EXCP_INVAL: EXCP_DUMP(env, "Invalid instruction\n"); info.si_signo = SIGILL; info.si_errno = 0; switch (env->error_code & 0xF) { case POWERPC_EXCP_INVAL_INVAL: info.si_code = ILL_ILLOPC; break; case POWERPC_EXCP_INVAL_LSWX: info.si_code = ILL_ILLOPN; break; case POWERPC_EXCP_INVAL_SPR: info.si_code = ILL_PRVREG; break; case POWERPC_EXCP_INVAL_FP: info.si_code = ILL_COPROC; break; default: EXCP_DUMP(env, "Unknown invalid operation (%02x)\n", env->error_code & 0xF); info.si_code = ILL_ILLADR; break; } /* Handle this via the gdb */ gdb_handlesig (env, SIGSEGV); break; case POWERPC_EXCP_PRIV: EXCP_DUMP(env, "Privilege violation\n"); info.si_signo = SIGILL; info.si_errno = 0; switch (env->error_code & 0xF) { case POWERPC_EXCP_PRIV_OPC: info.si_code = ILL_PRVOPC; break; case POWERPC_EXCP_PRIV_REG: info.si_code = ILL_PRVREG; break; default: EXCP_DUMP(env, "Unknown privilege violation (%02x)\n", env->error_code & 0xF); info.si_code = ILL_PRVOPC; break; } break; case POWERPC_EXCP_TRAP: cpu_abort(env, "Tried to call a TRAP\n"); break; default: /* Should not happen ! */ cpu_abort(env, "Unknown program exception (%02x)\n", env->error_code); break; } info.si_addr = (void*)(env->nip - 4); queue_signal(info.si_signo, &info); break; case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ EXCP_DUMP(env, "No floating point allowed\n"); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_COPROC; info.si_addr = (void*)(env->nip - 4); queue_signal(info.si_signo, &info); break; case POWERPC_EXCP_SYSCALL: /* System call exception */ cpu_abort(env, "Syscall exception while in user mode. " "Aborting\n"); break; case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ EXCP_DUMP(env, "No APU instruction allowed\n"); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_COPROC; info.si_addr = (void*)(env->nip - 4); queue_signal(info.si_signo, &info); break; case POWERPC_EXCP_DECR: /* Decrementer exception */ cpu_abort(env, "Decrementer interrupt while in user mode. " "Aborting\n"); break; case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ cpu_abort(env, "Fix interval timer interrupt while in user mode. " "Aborting\n"); break; case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ cpu_abort(env, "Watchdog timer interrupt while in user mode. " "Aborting\n"); break; case POWERPC_EXCP_DTLB: /* Data TLB error */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -