Commit 61190b14fc96d4e19c9bdde25643be4c5eb90e62
1 parent
9886cc16
PowerPC update (Jocelyn Mayer)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@536 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
315 additions
and
86 deletions
linux-user/main.c
| ... | ... | @@ -59,44 +59,44 @@ void gemu_log(const char *fmt, ...) |
| 59 | 59 | va_end(ap); |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | -#ifdef TARGET_I386 | |
| 63 | -/***********************************************************/ | |
| 64 | -/* CPUX86 core interface */ | |
| 65 | - | |
| 66 | -void cpu_x86_outb(CPUX86State *env, int addr, int val) | |
| 62 | +void cpu_outb(CPUState *env, int addr, int val) | |
| 67 | 63 | { |
| 68 | 64 | fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); |
| 69 | 65 | } |
| 70 | 66 | |
| 71 | -void cpu_x86_outw(CPUX86State *env, int addr, int val) | |
| 67 | +void cpu_outw(CPUState *env, int addr, int val) | |
| 72 | 68 | { |
| 73 | 69 | fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); |
| 74 | 70 | } |
| 75 | 71 | |
| 76 | -void cpu_x86_outl(CPUX86State *env, int addr, int val) | |
| 72 | +void cpu_outl(CPUState *env, int addr, int val) | |
| 77 | 73 | { |
| 78 | 74 | fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); |
| 79 | 75 | } |
| 80 | 76 | |
| 81 | -int cpu_x86_inb(CPUX86State *env, int addr) | |
| 77 | +int cpu_inb(CPUState *env, int addr) | |
| 82 | 78 | { |
| 83 | 79 | fprintf(stderr, "inb: port=0x%04x\n", addr); |
| 84 | 80 | return 0; |
| 85 | 81 | } |
| 86 | 82 | |
| 87 | -int cpu_x86_inw(CPUX86State *env, int addr) | |
| 83 | +int cpu_inw(CPUState *env, int addr) | |
| 88 | 84 | { |
| 89 | 85 | fprintf(stderr, "inw: port=0x%04x\n", addr); |
| 90 | 86 | return 0; |
| 91 | 87 | } |
| 92 | 88 | |
| 93 | -int cpu_x86_inl(CPUX86State *env, int addr) | |
| 89 | +int cpu_inl(CPUState *env, int addr) | |
| 94 | 90 | { |
| 95 | 91 | fprintf(stderr, "inl: port=0x%04x\n", addr); |
| 96 | 92 | return 0; |
| 97 | 93 | } |
| 98 | 94 | |
| 99 | -int cpu_x86_get_pic_interrupt(CPUX86State *env) | |
| 95 | +#ifdef TARGET_I386 | |
| 96 | +/***********************************************************/ | |
| 97 | +/* CPUX86 core interface */ | |
| 98 | + | |
| 99 | +int cpu_x86_get_pic_interrupt(CPUState *env) | |
| 100 | 100 | { |
| 101 | 101 | return -1; |
| 102 | 102 | } |
| ... | ... | @@ -428,119 +428,346 @@ void cpu_loop (CPUSPARCState *env) |
| 428 | 428 | |
| 429 | 429 | void cpu_loop(CPUPPCState *env) |
| 430 | 430 | { |
| 431 | - int trapnr; | |
| 432 | 431 | target_siginfo_t info; |
| 432 | + int trapnr; | |
| 433 | + uint32_t ret; | |
| 433 | 434 | |
| 434 | 435 | for(;;) { |
| 435 | 436 | trapnr = cpu_ppc_exec(env); |
| 437 | + if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH && | |
| 438 | + trapnr != EXCP_TRACE) { | |
| 439 | + if (loglevel > 0) { | |
| 440 | + cpu_ppc_dump_state(env, logfile, 0); | |
| 441 | + } | |
| 442 | + } | |
| 436 | 443 | switch(trapnr) { |
| 437 | 444 | case EXCP_NONE: |
| 438 | - case EXCP_INTERRUPT: | |
| 439 | - case EXCP_MTMSR: /* mtmsr instruction: */ | |
| 440 | - case EXCP_BRANCH: /* branch instruction */ | |
| 441 | - /* Single step mode */ | |
| 442 | 445 | break; |
| 446 | + case EXCP_SYSCALL_USER: | |
| 447 | + /* system call */ | |
| 448 | + /* WARNING: | |
| 449 | + * PPC ABI uses overflow flag in cr0 to signal an error | |
| 450 | + * in syscalls. | |
| 451 | + */ | |
| 443 | 452 | #if 0 |
| 444 | - case EXCP_RESET: /* System reset */ | |
| 445 | - fprintf(stderr, "RESET asked... Stop emulation\n"); | |
| 446 | - cpu_ppc_dump_state(env, stderr, 0); | |
| 447 | - abort(); | |
| 453 | + printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0], | |
| 454 | + env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]); | |
| 448 | 455 | #endif |
| 449 | - case EXCP_MACHINE_CHECK: /* Machine check exception */ | |
| 450 | - fprintf(stderr, "Machine check exeption... " | |
| 451 | - "See you in kernel code !\n"); | |
| 452 | - cpu_ppc_dump_state(env, stderr, 0); | |
| 456 | + env->crf[0] &= ~0x1; | |
| 457 | + ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], | |
| 458 | + env->gpr[5], env->gpr[6], env->gpr[7], | |
| 459 | + env->gpr[8]); | |
| 460 | + if (ret > (uint32_t)(-515)) { | |
| 461 | + env->crf[0] |= 0x1; | |
| 462 | + ret = -ret; | |
| 463 | + } | |
| 464 | + env->gpr[3] = ret; | |
| 465 | +#if 0 | |
| 466 | + printf("syscall returned 0x%08x (%d)\n", ret, ret); | |
| 467 | +#endif | |
| 468 | + break; | |
| 469 | + case EXCP_RESET: | |
| 470 | + /* Should not happen ! */ | |
| 471 | + fprintf(stderr, "RESET asked... Stop emulation\n"); | |
| 472 | + if (loglevel) | |
| 473 | + fprintf(logfile, "RESET asked... Stop emulation\n"); | |
| 453 | 474 | abort(); |
| 454 | - case EXCP_DSI: /* Impossible memory access */ | |
| 455 | - fprintf(stderr, "Invalid memory access\n"); | |
| 456 | - info.si_signo = SIGSEGV; | |
| 475 | + case EXCP_MACHINE_CHECK: | |
| 476 | + fprintf(stderr, "Machine check exeption... Stop emulation\n"); | |
| 477 | + if (loglevel) | |
| 478 | + fprintf(logfile, "RESET asked... Stop emulation\n"); | |
| 479 | + info.si_signo = TARGET_SIGBUS; | |
| 457 | 480 | info.si_errno = 0; |
| 458 | - info.si_code = TARGET_ILL_ILLOPN; | |
| 481 | + info.si_code = TARGET_BUS_OBJERR; | |
| 482 | + info._sifields._sigfault._addr = env->nip - 4; | |
| 483 | + queue_signal(info.si_signo, &info); | |
| 484 | + case EXCP_DSI: | |
| 485 | + fprintf(stderr, "Invalid data memory access: 0x%08x\n", env->spr[DAR]); | |
| 486 | + if (loglevel) { | |
| 487 | + fprintf(logfile, "Invalid data memory access: 0x%08x\n", | |
| 488 | + env->spr[DAR]); | |
| 489 | + } | |
| 490 | + switch (env->error_code & 0xF) { | |
| 491 | + case EXCP_DSI_TRANSLATE: | |
| 492 | + info.si_signo = TARGET_SIGSEGV; | |
| 493 | + info.si_errno = 0; | |
| 494 | + info.si_code = TARGET_SEGV_MAPERR; | |
| 495 | + break; | |
| 496 | + case EXCP_DSI_NOTSUP: | |
| 497 | + case EXCP_DSI_EXTERNAL: | |
| 498 | + info.si_signo = TARGET_SIGILL; | |
| 499 | + info.si_errno = 0; | |
| 500 | + info.si_code = TARGET_ILL_ILLADR; | |
| 501 | + break; | |
| 502 | + case EXCP_DSI_PROT: | |
| 503 | + info.si_signo = TARGET_SIGSEGV; | |
| 504 | + info.si_errno = 0; | |
| 505 | + info.si_code = TARGET_SEGV_ACCERR; | |
| 506 | + break; | |
| 507 | + case EXCP_DSI_DABR: | |
| 508 | + info.si_signo = TARGET_SIGTRAP; | |
| 509 | + info.si_errno = 0; | |
| 510 | + info.si_code = TARGET_TRAP_BRKPT; | |
| 511 | + break; | |
| 512 | + default: | |
| 513 | + /* Let's send a regular segfault... */ | |
| 514 | + fprintf(stderr, "Invalid segfault errno (%02x)\n", | |
| 515 | + env->error_code); | |
| 516 | + if (loglevel) { | |
| 517 | + fprintf(logfile, "Invalid segfault errno (%02x)\n", | |
| 518 | + env->error_code); | |
| 519 | + } | |
| 520 | + info.si_signo = TARGET_SIGSEGV; | |
| 521 | + info.si_errno = 0; | |
| 522 | + info.si_code = TARGET_SEGV_MAPERR; | |
| 523 | + break; | |
| 524 | + } | |
| 459 | 525 | info._sifields._sigfault._addr = env->nip; |
| 460 | 526 | queue_signal(info.si_signo, &info); |
| 461 | 527 | break; |
| 462 | - case EXCP_ISI: /* Impossible instruction fetch */ | |
| 528 | + case EXCP_ISI: | |
| 463 | 529 | fprintf(stderr, "Invalid instruction fetch\n"); |
| 464 | - info.si_signo = SIGBUS; | |
| 530 | + if (loglevel) | |
| 531 | + fprintf(logfile, "Invalid instruction fetch\n"); | |
| 532 | + switch (env->error_code) { | |
| 533 | + case EXCP_ISI_TRANSLATE: | |
| 534 | + info.si_signo = TARGET_SIGSEGV; | |
| 465 | 535 | info.si_errno = 0; |
| 466 | - info.si_code = TARGET_ILL_ILLOPN; | |
| 467 | - info._sifields._sigfault._addr = env->nip; | |
| 536 | + info.si_code = TARGET_SEGV_MAPERR; | |
| 537 | + break; | |
| 538 | + case EXCP_ISI_GUARD: | |
| 539 | + info.si_signo = TARGET_SIGILL; | |
| 540 | + info.si_errno = 0; | |
| 541 | + info.si_code = TARGET_ILL_ILLADR; | |
| 542 | + break; | |
| 543 | + case EXCP_ISI_NOEXEC: | |
| 544 | + case EXCP_ISI_PROT: | |
| 545 | + info.si_signo = TARGET_SIGSEGV; | |
| 546 | + info.si_errno = 0; | |
| 547 | + info.si_code = TARGET_SEGV_ACCERR; | |
| 548 | + break; | |
| 549 | + default: | |
| 550 | + /* Let's send a regular segfault... */ | |
| 551 | + fprintf(stderr, "Invalid segfault errno (%02x)\n", | |
| 552 | + env->error_code); | |
| 553 | + if (loglevel) { | |
| 554 | + fprintf(logfile, "Invalid segfault errno (%02x)\n", | |
| 555 | + env->error_code); | |
| 556 | + } | |
| 557 | + info.si_signo = TARGET_SIGSEGV; | |
| 558 | + info.si_errno = 0; | |
| 559 | + info.si_code = TARGET_SEGV_MAPERR; | |
| 560 | + break; | |
| 561 | + } | |
| 562 | + info._sifields._sigfault._addr = env->nip - 4; | |
| 468 | 563 | queue_signal(info.si_signo, &info); |
| 469 | 564 | break; |
| 470 | - case EXCP_EXTERNAL: /* External interruption */ | |
| 471 | - fprintf(stderr, "External access exeption\n"); | |
| 472 | - cpu_ppc_dump_state(env, stderr, 0); | |
| 473 | - abort(); | |
| 474 | - case EXCP_ALIGN: /* Alignment exception */ | |
| 475 | - fprintf(stderr, "Alignment exception\n"); | |
| 476 | - cpu_ppc_dump_state(env, stderr, 0); | |
| 477 | - abort(); | |
| 478 | - case EXCP_PROGRAM: /* Program exception */ | |
| 479 | - fprintf(stderr, "Program exception\n"); | |
| 480 | - cpu_ppc_dump_state(env, stderr, 0); | |
| 565 | + case EXCP_EXTERNAL: | |
| 566 | + /* Should not happen ! */ | |
| 567 | + fprintf(stderr, "External interruption... Stop emulation\n"); | |
| 568 | + if (loglevel) | |
| 569 | + fprintf(logfile, "External interruption... Stop emulation\n"); | |
| 481 | 570 | abort(); |
| 482 | - break; | |
| 483 | - /* Trap */ | |
| 484 | - case EXCP_TRAP: /* Trap */ | |
| 485 | - case EXCP_TRACE: /* Trace exception (optional) */ | |
| 486 | - info.si_signo = SIGTRAP; | |
| 571 | + case EXCP_ALIGN: | |
| 572 | + fprintf(stderr, "Invalid unaligned memory access\n"); | |
| 573 | + if (loglevel) | |
| 574 | + fprintf(logfile, "Invalid unaligned memory access\n"); | |
| 575 | + info.si_signo = TARGET_SIGBUS; | |
| 487 | 576 | info.si_errno = 0; |
| 488 | - info.si_code = TARGET_ILL_ILLOPN; | |
| 489 | - info._sifields._sigfault._addr = env->nip; | |
| 577 | + info.si_code = TARGET_BUS_ADRALN; | |
| 578 | + info._sifields._sigfault._addr = env->nip - 4; | |
| 490 | 579 | queue_signal(info.si_signo, &info); |
| 491 | 580 | break; |
| 492 | - /* Invalid instruction */ | |
| 581 | + case EXCP_PROGRAM: | |
| 582 | + switch (env->error_code & ~0xF) { | |
| 583 | + case EXCP_FP: | |
| 584 | + fprintf(stderr, "Program exception\n"); | |
| 585 | + if (loglevel) | |
| 586 | + fprintf(logfile, "Program exception\n"); | |
| 587 | + /* Set FX */ | |
| 588 | + env->fpscr[7] |= 0x8; | |
| 589 | + /* Finally, update FEX */ | |
| 590 | + if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) & | |
| 591 | + ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3))) | |
| 592 | + env->fpscr[7] |= 0x4; | |
| 593 | + info.si_signo = TARGET_SIGFPE; | |
| 594 | + info.si_errno = 0; | |
| 595 | + switch (env->error_code & 0xF) { | |
| 596 | + case EXCP_FP_OX: | |
| 597 | + info.si_code = TARGET_FPE_FLTOVF; | |
| 598 | + break; | |
| 599 | + case EXCP_FP_UX: | |
| 600 | + info.si_code = TARGET_FPE_FLTUND; | |
| 601 | + break; | |
| 602 | + case EXCP_FP_ZX: | |
| 603 | + case EXCP_FP_VXZDZ: | |
| 604 | + info.si_code = TARGET_FPE_FLTDIV; | |
| 605 | + break; | |
| 606 | + case EXCP_FP_XX: | |
| 607 | + info.si_code = TARGET_FPE_FLTRES; | |
| 608 | + break; | |
| 609 | + case EXCP_FP_VXSOFT: | |
| 610 | + info.si_code = TARGET_FPE_FLTINV; | |
| 611 | + break; | |
| 612 | + case EXCP_FP_VXNAN: | |
| 613 | + case EXCP_FP_VXISI: | |
| 614 | + case EXCP_FP_VXIDI: | |
| 615 | + case EXCP_FP_VXIMZ: | |
| 616 | + case EXCP_FP_VXVC: | |
| 617 | + case EXCP_FP_VXSQRT: | |
| 618 | + case EXCP_FP_VXCVI: | |
| 619 | + info.si_code = TARGET_FPE_FLTSUB; | |
| 620 | + break; | |
| 621 | + default: | |
| 622 | + fprintf(stderr, "Unknown floating point exception " | |
| 623 | + "(%02x)\n", env->error_code); | |
| 624 | + if (loglevel) { | |
| 625 | + fprintf(logfile, "Unknown floating point exception " | |
| 626 | + "(%02x)\n", env->error_code & 0xF); | |
| 627 | + } | |
| 628 | + } | |
| 629 | + break; | |
| 493 | 630 | case EXCP_INVAL: |
| 494 | - info.si_signo = SIGILL; | |
| 495 | - info.si_errno = 0; | |
| 631 | + fprintf(stderr, "Invalid instruction\n"); | |
| 632 | + if (loglevel) | |
| 633 | + fprintf(logfile, "Invalid instruction\n"); | |
| 634 | + info.si_signo = TARGET_SIGILL; | |
| 635 | + info.si_errno = 0; | |
| 636 | + switch (env->error_code & 0xF) { | |
| 637 | + case EXCP_INVAL_INVAL: | |
| 638 | + info.si_code = TARGET_ILL_ILLOPC; | |
| 639 | + break; | |
| 640 | + case EXCP_INVAL_LSWX: | |
| 496 | 641 | info.si_code = TARGET_ILL_ILLOPN; |
| 497 | - info._sifields._sigfault._addr = env->nip; | |
| 642 | + break; | |
| 643 | + case EXCP_INVAL_SPR: | |
| 644 | + info.si_code = TARGET_ILL_PRVREG; | |
| 645 | + break; | |
| 646 | + case EXCP_INVAL_FP: | |
| 647 | + info.si_code = TARGET_ILL_COPROC; | |
| 648 | + break; | |
| 649 | + default: | |
| 650 | + fprintf(stderr, "Unknown invalid operation (%02x)\n", | |
| 651 | + env->error_code & 0xF); | |
| 652 | + if (loglevel) { | |
| 653 | + fprintf(logfile, "Unknown invalid operation (%02x)\n", | |
| 654 | + env->error_code & 0xF); | |
| 655 | + } | |
| 656 | + info.si_code = TARGET_ILL_ILLADR; | |
| 657 | + break; | |
| 658 | + } | |
| 659 | + break; | |
| 660 | + case EXCP_PRIV: | |
| 661 | + fprintf(stderr, "Privilege violation\n"); | |
| 662 | + if (loglevel) | |
| 663 | + fprintf(logfile, "Privilege violation\n"); | |
| 664 | + info.si_signo = TARGET_SIGILL; | |
| 665 | + info.si_errno = 0; | |
| 666 | + switch (env->error_code & 0xF) { | |
| 667 | + case EXCP_PRIV_OPC: | |
| 668 | + info.si_code = TARGET_ILL_PRVOPC; | |
| 669 | + break; | |
| 670 | + case EXCP_PRIV_REG: | |
| 671 | + info.si_code = TARGET_ILL_PRVREG; | |
| 672 | + break; | |
| 673 | + default: | |
| 674 | + fprintf(stderr, "Unknown privilege violation (%02x)\n", | |
| 675 | + env->error_code & 0xF); | |
| 676 | + info.si_code = TARGET_ILL_PRVOPC; | |
| 677 | + break; | |
| 678 | + } | |
| 679 | + break; | |
| 680 | + case EXCP_TRAP: | |
| 681 | + fprintf(stderr, "Tried to call a TRAP\n"); | |
| 682 | + if (loglevel) | |
| 683 | + fprintf(logfile, "Tried to call a TRAP\n"); | |
| 684 | + abort(); | |
| 685 | + default: | |
| 686 | + /* Should not happen ! */ | |
| 687 | + fprintf(stderr, "Unknown program exception (%02x)\n", | |
| 688 | + env->error_code); | |
| 689 | + if (loglevel) { | |
| 690 | + fprintf(logfile, "Unknwon program exception (%02x)\n", | |
| 691 | + env->error_code); | |
| 692 | + } | |
| 693 | + abort(); | |
| 694 | + } | |
| 695 | + info._sifields._sigfault._addr = env->nip - 4; | |
| 498 | 696 | queue_signal(info.si_signo, &info); |
| 499 | 697 | break; |
| 500 | - /* Privileged instruction */ | |
| 501 | - case EXCP_PRIV: /* Privileged instruction */ | |
| 502 | - info.si_signo = SIGILL; | |
| 698 | + case EXCP_NO_FP: | |
| 699 | + fprintf(stderr, "No floating point allowed\n"); | |
| 700 | + if (loglevel) | |
| 701 | + fprintf(logfile, "No floating point allowed\n"); | |
| 702 | + info.si_signo = TARGET_SIGILL; | |
| 503 | 703 | info.si_errno = 0; |
| 504 | - info.si_code = TARGET_ILL_ILLOPN; | |
| 505 | - info._sifields._sigfault._addr = env->nip; | |
| 704 | + info.si_code = TARGET_ILL_COPROC; | |
| 705 | + info._sifields._sigfault._addr = env->nip - 4; | |
| 506 | 706 | queue_signal(info.si_signo, &info); |
| 507 | 707 | break; |
| 508 | - case EXCP_NO_FP: /* No floating point */ | |
| 509 | - case EXCP_DECR: /* Decrementer exception */ | |
| 708 | + case EXCP_DECR: | |
| 709 | + /* Should not happen ! */ | |
| 710 | + fprintf(stderr, "Decrementer exception\n"); | |
| 711 | + if (loglevel) | |
| 712 | + fprintf(logfile, "Decrementer exception\n"); | |
| 713 | + abort(); | |
| 510 | 714 | case EXCP_RESA: /* Implementation specific */ |
| 715 | + /* Should not happen ! */ | |
| 716 | + fprintf(stderr, "RESA exception should never happen !\n"); | |
| 717 | + if (loglevel) | |
| 718 | + fprintf(logfile, "RESA exception should never happen !\n"); | |
| 719 | + abort(); | |
| 511 | 720 | case EXCP_RESB: /* Implementation specific */ |
| 512 | - case EXCP_FP_ASSIST: /* Floating-point assist (optional) */ | |
| 513 | - fprintf(stderr, "Misc expt...\n"); | |
| 514 | - cpu_ppc_dump_state(env, stderr, 0); | |
| 721 | + /* Should not happen ! */ | |
| 722 | + fprintf(stderr, "RESB exception should never happen !\n"); | |
| 723 | + if (loglevel) | |
| 724 | + fprintf(logfile, "RESB exception should never happen !\n"); | |
| 515 | 725 | abort(); |
| 516 | - | |
| 517 | - case EXCP_SYSCALL: | |
| 518 | - { | |
| 519 | - uint32_t ret; | |
| 520 | - /* system call */ | |
| 521 | - /* WARNING: | |
| 522 | - * PPC ABI uses overflow flag in cr0 to signal an error | |
| 523 | - * in syscalls. | |
| 524 | - */ | |
| 525 | - env->crf[0] &= ~0x1; | |
| 526 | - ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], | |
| 527 | - env->gpr[5], env->gpr[6], env->gpr[7], | |
| 528 | - env->gpr[8]); | |
| 529 | - if (ret > (uint32_t)(-515)) { | |
| 530 | - env->crf[0] |= 0x1; | |
| 531 | - ret = -ret; | |
| 532 | - } | |
| 533 | - env->gpr[3] = ret; | |
| 726 | + case EXCP_TRACE: | |
| 727 | + /* Do nothing: we use this to trace execution */ | |
| 534 | 728 | break; |
| 729 | + case EXCP_FP_ASSIST: | |
| 730 | + /* Should not happen ! */ | |
| 731 | + fprintf(stderr, "Floating point assist exception\n"); | |
| 732 | + if (loglevel) | |
| 733 | + fprintf(logfile, "Floating point assist exception\n"); | |
| 734 | + abort(); | |
| 735 | + case EXCP_MTMSR: | |
| 736 | + /* We reloaded the msr, just go on */ | |
| 737 | + if (msr_pr) { | |
| 738 | + fprintf(stderr, "Tried to go into supervisor mode !\n"); | |
| 739 | + if (loglevel) | |
| 740 | + fprintf(logfile, "Tried to go into supervisor mode !\n"); | |
| 741 | + abort(); | |
| 535 | 742 | } |
| 743 | + break; | |
| 744 | + case EXCP_BRANCH: | |
| 745 | + /* We stopped because of a jump... */ | |
| 746 | + break; | |
| 747 | + case EXCP_RFI: | |
| 748 | + /* Should not occur: we always are in user mode */ | |
| 749 | + fprintf(stderr, "Return from interrupt ?\n"); | |
| 750 | + if (loglevel) | |
| 751 | + fprintf(logfile, "Return from interrupt ?\n"); | |
| 752 | + abort(); | |
| 753 | + case EXCP_INTERRUPT: | |
| 754 | + /* Don't know why this should ever happen... */ | |
| 755 | + break; | |
| 536 | 756 | default: |
| 537 | -// error: | |
| 538 | 757 | fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
| 539 | 758 | trapnr); |
| 540 | - cpu_ppc_dump_state(env, stderr, 0); | |
| 759 | + if (loglevel) { | |
| 760 | + fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - " | |
| 761 | + "0x%02x - aborting\n", trapnr, env->error_code); | |
| 762 | + } | |
| 541 | 763 | abort(); |
| 542 | 764 | } |
| 765 | + if (trapnr < EXCP_PPC_MAX) | |
| 766 | + env->exceptions &= ~(1 << trapnr); | |
| 543 | 767 | process_pending_signals(env); |
| 768 | + if (env->exceptions != 0) { | |
| 769 | + check_exception_state(env); | |
| 770 | + } | |
| 544 | 771 | } |
| 545 | 772 | } |
| 546 | 773 | #endif |
| ... | ... | @@ -750,8 +977,10 @@ int main(int argc, char **argv) |
| 750 | 977 | #elif defined(TARGET_PPC) |
| 751 | 978 | { |
| 752 | 979 | int i; |
| 753 | - for (i = 0; i < 32; i++) | |
| 754 | - env->msr[i] = (regs->msr >> i) & 1; | |
| 980 | + for (i = 0; i < 32; i++) { | |
| 981 | + if (i != 12 && i != 6) | |
| 982 | + env->msr[i] = (regs->msr >> i) & 1; | |
| 983 | + } | |
| 755 | 984 | env->nip = regs->nip; |
| 756 | 985 | for(i = 0; i < 32; i++) { |
| 757 | 986 | env->gpr[i] = regs->gpr[i]; | ... | ... |