Revision 67867308 linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
324 | 324 |
|
325 | 325 |
#endif |
326 | 326 |
|
327 |
#ifdef TARGET_PPC |
|
328 |
|
|
329 |
void cpu_loop(CPUPPCState *env) |
|
330 |
{ |
|
331 |
int trapnr; |
|
332 |
target_siginfo_t info; |
|
333 |
|
|
334 |
for(;;) { |
|
335 |
trapnr = cpu_ppc_exec(env); |
|
336 |
switch(trapnr) { |
|
337 |
case EXCP_NONE: |
|
338 |
case EXCP_INTERRUPT: |
|
339 |
case EXCP_MTMSR: /* mtmsr instruction: */ |
|
340 |
case EXCP_BRANCH: /* branch instruction */ |
|
341 |
/* Single step mode */ |
|
342 |
break; |
|
343 |
#if 0 |
|
344 |
case EXCP_RESET: /* System reset */ |
|
345 |
fprintf(stderr, "RESET asked... Stop emulation\n"); |
|
346 |
cpu_ppc_dump_state(env, stderr, 0); |
|
347 |
abort(); |
|
348 |
#endif |
|
349 |
case EXCP_MACHINE_CHECK: /* Machine check exception */ |
|
350 |
fprintf(stderr, "Machine check exeption... " |
|
351 |
"See you in kernel code !\n"); |
|
352 |
cpu_ppc_dump_state(env, stderr, 0); |
|
353 |
abort(); |
|
354 |
case EXCP_DSI: /* Impossible memory access */ |
|
355 |
fprintf(stderr, "Invalid memory access\n"); |
|
356 |
info.si_signo = SIGSEGV; |
|
357 |
info.si_errno = 0; |
|
358 |
info.si_code = TARGET_ILL_ILLOPN; |
|
359 |
info._sifields._sigfault._addr = env->nip; |
|
360 |
queue_signal(info.si_signo, &info); |
|
361 |
break; |
|
362 |
case EXCP_ISI: /* Impossible instruction fetch */ |
|
363 |
fprintf(stderr, "Invalid instruction fetch\n"); |
|
364 |
info.si_signo = SIGBUS; |
|
365 |
info.si_errno = 0; |
|
366 |
info.si_code = TARGET_ILL_ILLOPN; |
|
367 |
info._sifields._sigfault._addr = env->nip; |
|
368 |
queue_signal(info.si_signo, &info); |
|
369 |
break; |
|
370 |
case EXCP_EXTERNAL: /* External interruption */ |
|
371 |
fprintf(stderr, "External access exeption\n"); |
|
372 |
cpu_ppc_dump_state(env, stderr, 0); |
|
373 |
abort(); |
|
374 |
case EXCP_ALIGN: /* Alignment exception */ |
|
375 |
fprintf(stderr, "Alignment exception\n"); |
|
376 |
cpu_ppc_dump_state(env, stderr, 0); |
|
377 |
abort(); |
|
378 |
case EXCP_PROGRAM: /* Program exception */ |
|
379 |
fprintf(stderr, "Program exception\n"); |
|
380 |
cpu_ppc_dump_state(env, stderr, 0); |
|
381 |
abort(); |
|
382 |
break; |
|
383 |
/* Trap */ |
|
384 |
case EXCP_TRAP: /* Trap */ |
|
385 |
case EXCP_TRACE: /* Trace exception (optional) */ |
|
386 |
info.si_signo = SIGTRAP; |
|
387 |
info.si_errno = 0; |
|
388 |
info.si_code = TARGET_ILL_ILLOPN; |
|
389 |
info._sifields._sigfault._addr = env->nip; |
|
390 |
queue_signal(info.si_signo, &info); |
|
391 |
break; |
|
392 |
/* Invalid instruction */ |
|
393 |
case EXCP_INVAL: |
|
394 |
info.si_signo = SIGILL; |
|
395 |
info.si_errno = 0; |
|
396 |
info.si_code = TARGET_ILL_ILLOPN; |
|
397 |
info._sifields._sigfault._addr = env->nip; |
|
398 |
queue_signal(info.si_signo, &info); |
|
399 |
break; |
|
400 |
/* Privileged instruction */ |
|
401 |
case EXCP_PRIV: /* Privileged instruction */ |
|
402 |
info.si_signo = SIGILL; |
|
403 |
info.si_errno = 0; |
|
404 |
info.si_code = TARGET_ILL_ILLOPN; |
|
405 |
info._sifields._sigfault._addr = env->nip; |
|
406 |
queue_signal(info.si_signo, &info); |
|
407 |
break; |
|
408 |
case EXCP_NO_FP: /* No floating point */ |
|
409 |
case EXCP_DECR: /* Decrementer exception */ |
|
410 |
case EXCP_RESA: /* Implementation specific */ |
|
411 |
case EXCP_RESB: /* Implementation specific */ |
|
412 |
case EXCP_FP_ASSIST: /* Floating-point assist (optional) */ |
|
413 |
fprintf(stderr, "Misc expt...\n"); |
|
414 |
cpu_ppc_dump_state(env, stderr, 0); |
|
415 |
abort(); |
|
416 |
|
|
417 |
case EXCP_SYSCALL: |
|
418 |
{ |
|
419 |
uint32_t ret; |
|
420 |
/* system call */ |
|
421 |
/* WARNING: |
|
422 |
* PPC ABI uses overflow flag in cr0 to signal an error |
|
423 |
* in syscalls. |
|
424 |
*/ |
|
425 |
env->crf[0] &= ~0x1; |
|
426 |
ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], |
|
427 |
env->gpr[5], env->gpr[6], env->gpr[7], |
|
428 |
env->gpr[8]); |
|
429 |
if (ret > (uint32_t)(-515)) { |
|
430 |
env->crf[0] |= 0x1; |
|
431 |
ret = -ret; |
|
432 |
} |
|
433 |
env->gpr[3] = ret; |
|
434 |
break; |
|
435 |
} |
|
436 |
default: |
|
437 |
// error: |
|
438 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
|
439 |
trapnr); |
|
440 |
cpu_ppc_dump_state(env, stderr, 0); |
|
441 |
abort(); |
|
442 |
} |
|
443 |
process_pending_signals(env); |
|
444 |
} |
|
445 |
} |
|
446 |
#endif |
|
447 |
|
|
327 | 448 |
void usage(void) |
328 | 449 |
{ |
329 | 450 |
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" |
... | ... | |
517 | 638 |
#elif defined(TARGET_SPARC) |
518 | 639 |
env->pc = regs->u_regs[0]; |
519 | 640 |
env->regwptr[6] = regs->u_regs[1]-0x40; |
641 |
#elif defined(TARGET_PPC) |
|
642 |
{ |
|
643 |
int i; |
|
644 |
for (i = 0; i < 32; i++) |
|
645 |
env->msr[i] = (regs->msr >> i) & 1; |
|
646 |
env->nip = regs->nip; |
|
647 |
for(i = 0; i < 32; i++) { |
|
648 |
env->gpr[i] = regs->gpr[i]; |
|
649 |
} |
|
650 |
} |
|
520 | 651 |
#else |
521 | 652 |
#error unsupported target CPU |
522 | 653 |
#endif |
Also available in: Unified diff