Revision b346ff46 linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
63 | 63 |
va_end(ap); |
64 | 64 |
} |
65 | 65 |
|
66 |
#ifdef TARGET_I386 |
|
66 | 67 |
/***********************************************************/ |
67 | 68 |
/* CPUX86 core interface */ |
68 | 69 |
|
... | ... | |
238 | 239 |
process_pending_signals(env); |
239 | 240 |
} |
240 | 241 |
} |
242 |
#endif |
|
243 |
|
|
244 |
#ifdef TARGET_ARM |
|
245 |
|
|
246 |
#define ARM_SYSCALL_BASE 0x900000 |
|
247 |
|
|
248 |
void cpu_loop(CPUARMState *env) |
|
249 |
{ |
|
250 |
int trapnr; |
|
251 |
unsigned int n, insn; |
|
252 |
target_siginfo_t info; |
|
253 |
|
|
254 |
for(;;) { |
|
255 |
trapnr = cpu_arm_exec(env); |
|
256 |
switch(trapnr) { |
|
257 |
case EXCP_UDEF: |
|
258 |
info.si_signo = SIGILL; |
|
259 |
info.si_errno = 0; |
|
260 |
info.si_code = TARGET_ILL_ILLOPN; |
|
261 |
info._sifields._sigfault._addr = env->regs[15]; |
|
262 |
queue_signal(info.si_signo, &info); |
|
263 |
break; |
|
264 |
case EXCP_SWI: |
|
265 |
{ |
|
266 |
/* system call */ |
|
267 |
insn = ldl((void *)(env->regs[15] - 4)); |
|
268 |
n = insn & 0xffffff; |
|
269 |
if (n >= ARM_SYSCALL_BASE) { |
|
270 |
/* linux syscall */ |
|
271 |
n -= ARM_SYSCALL_BASE; |
|
272 |
env->regs[0] = do_syscall(env, |
|
273 |
n, |
|
274 |
env->regs[0], |
|
275 |
env->regs[1], |
|
276 |
env->regs[2], |
|
277 |
env->regs[3], |
|
278 |
env->regs[4], |
|
279 |
0); |
|
280 |
} else { |
|
281 |
goto error; |
|
282 |
} |
|
283 |
} |
|
284 |
break; |
|
285 |
default: |
|
286 |
error: |
|
287 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
|
288 |
trapnr); |
|
289 |
cpu_arm_dump_state(env, stderr, 0); |
|
290 |
abort(); |
|
291 |
} |
|
292 |
process_pending_signals(env); |
|
293 |
} |
|
294 |
} |
|
295 |
|
|
296 |
#endif |
|
241 | 297 |
|
242 | 298 |
void usage(void) |
243 | 299 |
{ |
244 | 300 |
printf("qemu version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" |
245 | 301 |
"usage: qemu [-h] [-d] [-L path] [-s size] program [arguments...]\n" |
246 |
"Linux x86 emulator\n"
|
|
302 |
"Linux CPU emulator (compiled for %s emulation)\n"
|
|
247 | 303 |
"\n" |
248 | 304 |
"-h print this help\n" |
249 |
"-L path set the x86 elf interpreter prefix (default=%s)\n"
|
|
250 |
"-s size set the x86 stack size in bytes (default=%ld)\n"
|
|
305 |
"-L path set the elf interpreter prefix (default=%s)\n" |
|
306 |
"-s size set the stack size in bytes (default=%ld)\n" |
|
251 | 307 |
"\n" |
252 | 308 |
"debug options:\n" |
253 | 309 |
"-d activate log (logfile=%s)\n" |
254 | 310 |
"-p pagesize set the host page size to 'pagesize'\n", |
311 |
TARGET_ARCH, |
|
255 | 312 |
interp_prefix, |
256 | 313 |
x86_stack_size, |
257 | 314 |
DEBUG_LOGFILE); |
... | ... | |
259 | 316 |
} |
260 | 317 |
|
261 | 318 |
/* XXX: currently only used for async signals (see signal.c) */ |
262 |
CPUX86State *global_env;
|
|
319 |
CPUState *global_env; |
|
263 | 320 |
/* used to free thread contexts */ |
264 | 321 |
TaskState *first_task_state; |
265 | 322 |
|
... | ... | |
269 | 326 |
struct target_pt_regs regs1, *regs = ®s1; |
270 | 327 |
struct image_info info1, *info = &info1; |
271 | 328 |
TaskState ts1, *ts = &ts1; |
272 |
CPUX86State *env;
|
|
329 |
CPUState *env; |
|
273 | 330 |
int optind; |
274 | 331 |
const char *r; |
275 | 332 |
|
... | ... | |
337 | 394 |
|
338 | 395 |
/* NOTE: we need to init the CPU at this stage to get the |
339 | 396 |
host_page_size */ |
340 |
env = cpu_x86_init();
|
|
397 |
env = cpu_init(); |
|
341 | 398 |
|
342 | 399 |
if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { |
343 | 400 |
printf("Error loading %s\n", filename); |
... | ... | |
353 | 410 |
fprintf(logfile, "end_data 0x%08lx\n" , info->end_data); |
354 | 411 |
fprintf(logfile, "start_stack 0x%08lx\n" , info->start_stack); |
355 | 412 |
fprintf(logfile, "brk 0x%08lx\n" , info->brk); |
356 |
fprintf(logfile, "esp 0x%08lx\n" , regs->esp); |
|
357 |
fprintf(logfile, "eip 0x%08lx\n" , regs->eip); |
|
413 |
fprintf(logfile, "entry 0x%08lx\n" , info->entry); |
|
358 | 414 |
} |
359 | 415 |
|
360 | 416 |
target_set_brk((char *)info->brk); |
... | ... | |
368 | 424 |
env->opaque = ts; |
369 | 425 |
ts->used = 1; |
370 | 426 |
|
427 |
#if defined(TARGET_I386) |
|
371 | 428 |
/* linux register setup */ |
372 | 429 |
env->regs[R_EAX] = regs->eax; |
373 | 430 |
env->regs[R_EBX] = regs->ebx; |
... | ... | |
419 | 476 |
cpu_x86_load_seg(env, R_SS, __USER_DS); |
420 | 477 |
cpu_x86_load_seg(env, R_FS, __USER_DS); |
421 | 478 |
cpu_x86_load_seg(env, R_GS, __USER_DS); |
479 |
#elif defined(TARGET_ARM) |
|
480 |
{ |
|
481 |
int i; |
|
482 |
for(i = 0; i < 16; i++) { |
|
483 |
env->regs[i] = regs->uregs[i]; |
|
484 |
} |
|
485 |
env->cpsr = regs->uregs[16]; |
|
486 |
} |
|
487 |
#else |
|
488 |
#error unsupported target CPU |
|
489 |
#endif |
|
422 | 490 |
|
423 | 491 |
cpu_loop(env); |
424 | 492 |
/* never exits */ |
Also available in: Unified diff