#include "qemu.h"
#include "qemu-common.h"
/* For tb_lock */
-#include "exec-all.h"
-
-
-#include "envlist.h"
-
-#define DEBUG_LOGFILE "/tmp/qemu.log"
+#include "cpu.h"
+#include "tcg.h"
+#include "qemu/timer.h"
+#include "qemu/envlist.h"
int singlestep;
#if defined(CONFIG_USE_GUEST_BASE)
unsigned long mmap_min_addr;
unsigned long guest_base;
int have_guest_base;
+unsigned long reserved_va;
#endif
-static const char *interp_prefix = CONFIG_QEMU_PREFIX;
+static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
extern char **environ;
+enum BSDType bsd_type;
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
we allocate a bigger stack. Need a better solution, for example
}
#if defined(TARGET_I386)
-int cpu_get_pic_interrupt(CPUState *env)
+int cpu_get_pic_interrupt(CPUX86State *env)
{
return -1;
}
#endif
/* These are no-ops because we are not threadsafe. */
-static inline void cpu_exec_start(CPUState *env)
+static inline void cpu_exec_start(CPUArchState *env)
{
}
-static inline void cpu_exec_end(CPUState *env)
+static inline void cpu_exec_end(CPUArchState *env)
{
}
/***********************************************************/
/* CPUX86 core interface */
-void cpu_smm_update(CPUState *env)
+void cpu_smm_update(CPUX86State *env)
{
}
}
#endif
-void cpu_loop(CPUX86State *env, enum BSDType bsd_type)
+void cpu_loop(CPUX86State *env)
{
int trapnr;
abi_ulong pc;
switch(trapnr) {
case 0x80:
/* syscall from int $0x80 */
- env->regs[R_EAX] = do_openbsd_syscall(env,
- env->regs[R_EAX],
- env->regs[R_EBX],
- env->regs[R_ECX],
- env->regs[R_EDX],
- env->regs[R_ESI],
- env->regs[R_EDI],
- env->regs[R_EBP]);
+ if (bsd_type == target_freebsd) {
+ abi_ulong params = (abi_ulong) env->regs[R_ESP] +
+ sizeof(int32_t);
+ int32_t syscall_nr = env->regs[R_EAX];
+ int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
+
+ if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
+ get_user_s32(syscall_nr, params);
+ params += sizeof(int32_t);
+ } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
+ get_user_s32(syscall_nr, params);
+ params += sizeof(int64_t);
+ }
+ get_user_s32(arg1, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg2, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg3, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg4, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg5, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg6, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg7, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg8, params);
+ env->regs[R_EAX] = do_freebsd_syscall(env,
+ syscall_nr,
+ arg1,
+ arg2,
+ arg3,
+ arg4,
+ arg5,
+ arg6,
+ arg7,
+ arg8);
+ } else { //if (bsd_type == target_openbsd)
+ env->regs[R_EAX] = do_openbsd_syscall(env,
+ env->regs[R_EAX],
+ env->regs[R_EBX],
+ env->regs[R_ECX],
+ env->regs[R_EDX],
+ env->regs[R_ESI],
+ env->regs[R_EDI],
+ env->regs[R_EBP]);
+ }
+ if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
+ env->regs[R_EAX] = -env->regs[R_EAX];
+ env->eflags |= CC_C;
+ } else {
+ env->eflags &= ~CC_C;
+ }
break;
#ifndef TARGET_ABI32
case EXCP_SYSCALL:
- /* linux syscall from syscall intruction */
- env->regs[R_EAX] = do_openbsd_syscall(env,
- env->regs[R_EAX],
- env->regs[R_EDI],
- env->regs[R_ESI],
- env->regs[R_EDX],
- env->regs[10],
- env->regs[8],
- env->regs[9]);
+ /* syscall from syscall instruction */
+ if (bsd_type == target_freebsd)
+ env->regs[R_EAX] = do_freebsd_syscall(env,
+ env->regs[R_EAX],
+ env->regs[R_EDI],
+ env->regs[R_ESI],
+ env->regs[R_EDX],
+ env->regs[R_ECX],
+ env->regs[8],
+ env->regs[9], 0, 0);
+ else { //if (bsd_type == target_openbsd)
+ env->regs[R_EAX] = do_openbsd_syscall(env,
+ env->regs[R_EAX],
+ env->regs[R_EDI],
+ env->regs[R_ESI],
+ env->regs[R_EDX],
+ env->regs[10],
+ env->regs[8],
+ env->regs[9]);
+ }
env->eip = env->exception_next_eip;
+ if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
+ env->regs[R_EAX] = -env->regs[R_EAX];
+ env->eflags |= CC_C;
+ } else {
+ env->eflags &= ~CC_C;
+ }
break;
#endif
#if 0
#endif
}
-void cpu_loop(CPUSPARCState *env, enum BSDType bsd_type)
+void cpu_loop(CPUSPARCState *env)
{
int trapnr, ret, syscall_nr;
//target_siginfo_t info;
#ifndef TARGET_SPARC64
case 0x80:
#else
+ /* FreeBSD uses 0x141 for syscalls too */
+ case 0x141:
+ if (bsd_type != target_freebsd)
+ goto badtrap;
case 0x100:
#endif
syscall_nr = env->gregs[1];
ret = do_freebsd_syscall(env, syscall_nr,
env->regwptr[0], env->regwptr[1],
env->regwptr[2], env->regwptr[3],
- env->regwptr[4], env->regwptr[5]);
+ env->regwptr[4], env->regwptr[5], 0, 0);
else if (bsd_type == target_netbsd)
ret = do_netbsd_syscall(env, syscall_nr,
env->regwptr[0], env->regwptr[1],
env->regwptr[4], env->regwptr[5]);
}
if ((unsigned int)ret >= (unsigned int)(-515)) {
+ ret = -ret;
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
env->xcc |= PSR_CARRY;
#else
}
break;
default:
+#ifdef TARGET_SPARC64
+ badtrap:
+#endif
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
exit (1);
"-g port wait gdb connection to port\n"
"-L path set the elf interpreter prefix (default=%s)\n"
"-s size set the stack size in bytes (default=%ld)\n"
- "-cpu model select CPU (-cpu ? for list)\n"
+ "-cpu model select CPU (-cpu help for list)\n"
"-drop-ld-preload drop LD_PRELOAD for target process\n"
"-E var=value sets/modifies targets environment variable(s)\n"
"-U var unsets targets environment variable(s)\n"
"-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n"
"\n"
"Debug options:\n"
- "-d options activate log (logfile=%s)\n"
- "-p pagesize set the host page size to 'pagesize'\n"
- "-singlestep always run in singlestep mode\n"
- "-strace log system calls\n"
+ "-d item1[,...] enable logging of specified items\n"
+ " (use '-d help' for a list of log items)\n"
+ "-D logfile write logs to 'logfile' (default stderr)\n"
+ "-p pagesize set the host page size to 'pagesize'\n"
+ "-singlestep always run in singlestep mode\n"
+ "-strace log system calls\n"
"\n"
"Environment variables:\n"
"QEMU_STRACE Print system calls and arguments similar to the\n"
,
TARGET_ARCH,
interp_prefix,
- x86_stack_size,
- DEBUG_LOGFILE);
+ x86_stack_size);
exit(1);
}
-THREAD CPUState *thread_env;
+THREAD CPUArchState *thread_env;
/* Assumes contents are already zeroed. */
void init_task_state(TaskState *ts)
{
const char *filename;
const char *cpu_model;
+ const char *log_file = NULL;
+ const char *log_mask = NULL;
struct target_pt_regs regs1, *regs = ®s1;
struct image_info info1, *info = &info1;
TaskState ts1, *ts = &ts1;
- CPUState *env;
+ CPUArchState *env;
int optind;
const char *r;
int gdbstub_port = 0;
char **target_environ, **wrk;
envlist_t *envlist = NULL;
- enum BSDType bsd_type = target_openbsd;
+ bsd_type = target_openbsd;
if (argc <= 1)
usage();
- /* init debug */
- cpu_set_log_filename(DEBUG_LOGFILE);
+ module_call_init(MODULE_INIT_QOM);
if ((envlist = envlist_create()) == NULL) {
(void) fprintf(stderr, "Unable to allocate envlist\n");
}
cpu_model = NULL;
+#if defined(cpudef_setup)
+ cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
+#endif
+
optind = 1;
for(;;) {
if (optind >= argc)
if (!strcmp(r, "-")) {
break;
} else if (!strcmp(r, "d")) {
- int mask;
- const CPULogItem *item;
-
- if (optind >= argc)
+ if (optind >= argc) {
break;
-
- r = argv[optind++];
- mask = cpu_str_to_log_mask(r);
- if (!mask) {
- printf("Log items (comma separated):\n");
- for(item = cpu_log_items; item->mask != 0; item++) {
- printf("%-10s %s\n", item->name, item->help);
- }
- exit(1);
}
- cpu_set_log(mask);
+ log_mask = argv[optind++];
+ } else if (!strcmp(r, "D")) {
+ if (optind >= argc) {
+ break;
+ }
+ log_file = argv[optind++];
} else if (!strcmp(r, "E")) {
r = argv[optind++];
if (envlist_setenv(envlist, r) != 0)
usage();
+ } else if (!strcmp(r, "ignore-environment")) {
+ envlist_free(envlist);
+ if ((envlist = envlist_create()) == NULL) {
+ (void) fprintf(stderr, "Unable to allocate envlist\n");
+ exit(1);
+ }
} else if (!strcmp(r, "U")) {
r = argv[optind++];
if (envlist_unsetenv(envlist, r) != 0)
qemu_uname_release = argv[optind++];
} else if (!strcmp(r, "cpu")) {
cpu_model = argv[optind++];
- if (strcmp(cpu_model, "?") == 0) {
+ if (is_help_option(cpu_model)) {
/* XXX: implement xxx_cpu_list for targets that still miss it */
#if defined(cpu_list)
cpu_list(stdout, &fprintf);
usage();
}
}
- if (optind >= argc)
+
+ /* init debug */
+ qemu_set_log_filename(log_file);
+ if (log_mask) {
+ int mask;
+
+ mask = qemu_str_to_log_mask(log_mask);
+ if (!mask) {
+ qemu_print_log_usage(stdout);
+ exit(1);
+ }
+ qemu_set_log(mask);
+ }
+
+ if (optind >= argc) {
usage();
+ }
filename = argv[optind];
/* Zero out regs */
cpu_model = "any";
#endif
}
- cpu_exec_init_all(0);
+ tcg_exec_init(0);
+ cpu_exec_init_all();
/* NOTE: we need to init the CPU at this stage to get
qemu_host_page_size */
env = cpu_init(cpu_model);
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
+ cpu_reset(ENV_GET_CPU(env));
+#endif
thread_env = env;
if (getenv("QEMU_STRACE")) {
syscall_init();
signal_init();
+#if defined(CONFIG_USE_GUEST_BASE)
+ /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
+ generating the prologue until now so that the prologue can take
+ the real value of GUEST_BASE into account. */
+ tcg_prologue_init(&tcg_ctx);
+#endif
+
/* build Task State */
memset(ts, 0, sizeof(TaskState));
init_task_state(ts);
gdbserver_start (gdbstub_port);
gdb_handlesig(env, 0);
}
- cpu_loop(env, bsd_type);
+ cpu_loop(env);
/* never exits */
return 0;
}