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,44 +59,44 @@ void gemu_log(const char *fmt, ...) | ||
59 | va_end(ap); | 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 | fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); | 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 | fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); | 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 | fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); | 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 | fprintf(stderr, "inb: port=0x%04x\n", addr); | 79 | fprintf(stderr, "inb: port=0x%04x\n", addr); |
84 | return 0; | 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 | fprintf(stderr, "inw: port=0x%04x\n", addr); | 85 | fprintf(stderr, "inw: port=0x%04x\n", addr); |
90 | return 0; | 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 | fprintf(stderr, "inl: port=0x%04x\n", addr); | 91 | fprintf(stderr, "inl: port=0x%04x\n", addr); |
96 | return 0; | 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 | return -1; | 101 | return -1; |
102 | } | 102 | } |
@@ -428,119 +428,346 @@ void cpu_loop (CPUSPARCState *env) | @@ -428,119 +428,346 @@ void cpu_loop (CPUSPARCState *env) | ||
428 | 428 | ||
429 | void cpu_loop(CPUPPCState *env) | 429 | void cpu_loop(CPUPPCState *env) |
430 | { | 430 | { |
431 | - int trapnr; | ||
432 | target_siginfo_t info; | 431 | target_siginfo_t info; |
432 | + int trapnr; | ||
433 | + uint32_t ret; | ||
433 | 434 | ||
434 | for(;;) { | 435 | for(;;) { |
435 | trapnr = cpu_ppc_exec(env); | 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 | switch(trapnr) { | 443 | switch(trapnr) { |
437 | case EXCP_NONE: | 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 | break; | 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 | #if 0 | 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 | #endif | 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 | abort(); | 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 | info.si_errno = 0; | 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 | info._sifields._sigfault._addr = env->nip; | 525 | info._sifields._sigfault._addr = env->nip; |
460 | queue_signal(info.si_signo, &info); | 526 | queue_signal(info.si_signo, &info); |
461 | break; | 527 | break; |
462 | - case EXCP_ISI: /* Impossible instruction fetch */ | 528 | + case EXCP_ISI: |
463 | fprintf(stderr, "Invalid instruction fetch\n"); | 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 | info.si_errno = 0; | 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 | queue_signal(info.si_signo, &info); | 563 | queue_signal(info.si_signo, &info); |
469 | break; | 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 | abort(); | 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 | info.si_errno = 0; | 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 | queue_signal(info.si_signo, &info); | 579 | queue_signal(info.si_signo, &info); |
491 | break; | 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 | case EXCP_INVAL: | 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 | info.si_code = TARGET_ILL_ILLOPN; | 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 | queue_signal(info.si_signo, &info); | 696 | queue_signal(info.si_signo, &info); |
499 | break; | 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 | info.si_errno = 0; | 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 | queue_signal(info.si_signo, &info); | 706 | queue_signal(info.si_signo, &info); |
507 | break; | 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 | case EXCP_RESA: /* Implementation specific */ | 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 | case EXCP_RESB: /* Implementation specific */ | 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 | abort(); | 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 | break; | 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 | default: | 756 | default: |
537 | -// error: | ||
538 | fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", | 757 | fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
539 | trapnr); | 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 | abort(); | 763 | abort(); |
542 | } | 764 | } |
765 | + if (trapnr < EXCP_PPC_MAX) | ||
766 | + env->exceptions &= ~(1 << trapnr); | ||
543 | process_pending_signals(env); | 767 | process_pending_signals(env); |
768 | + if (env->exceptions != 0) { | ||
769 | + check_exception_state(env); | ||
770 | + } | ||
544 | } | 771 | } |
545 | } | 772 | } |
546 | #endif | 773 | #endif |
@@ -750,8 +977,10 @@ int main(int argc, char **argv) | @@ -750,8 +977,10 @@ int main(int argc, char **argv) | ||
750 | #elif defined(TARGET_PPC) | 977 | #elif defined(TARGET_PPC) |
751 | { | 978 | { |
752 | int i; | 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 | env->nip = regs->nip; | 984 | env->nip = regs->nip; |
756 | for(i = 0; i < 32; i++) { | 985 | for(i = 0; i < 32; i++) { |
757 | env->gpr[i] = regs->gpr[i]; | 986 | env->gpr[i] = regs->gpr[i]; |