Commit 2be0071f22f5719eb5e2800f070547227ba37e5a

Authored by bellard
1 parent f68c781c

simplified PowerPC exception handling (Jocelyn Mayer)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1492 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-defs.h
@@ -68,9 +68,9 @@ typedef uint64_t target_phys_addr_t; @@ -68,9 +68,9 @@ typedef uint64_t target_phys_addr_t;
68 68
69 #define HOST_LONG_SIZE (HOST_LONG_BITS / 8) 69 #define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
70 70
71 -#define EXCP_INTERRUPT 256 /* async interruption */  
72 -#define EXCP_HLT 257 /* hlt instruction reached */  
73 -#define EXCP_DEBUG 258 /* cpu stopped after a breakpoint or singlestep */ 71 +#define EXCP_INTERRUPT 0x10000 /* async interruption */
  72 +#define EXCP_HLT 0x10001 /* hlt instruction reached */
  73 +#define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */
74 74
75 #define MAX_BREAKPOINTS 32 75 #define MAX_BREAKPOINTS 32
76 76
linux-user/main.c
@@ -706,28 +706,22 @@ void cpu_loop(CPUPPCState *env) @@ -706,28 +706,22 @@ void cpu_loop(CPUPPCState *env)
706 fprintf(logfile, "Invalid data memory access: 0x%08x\n", 706 fprintf(logfile, "Invalid data memory access: 0x%08x\n",
707 env->spr[SPR_DAR]); 707 env->spr[SPR_DAR]);
708 } 708 }
709 - switch (env->error_code & 0xF) {  
710 - case EXCP_DSI_TRANSLATE: 709 + switch (env->error_code & 0xFF000000) {
  710 + case 0x40000000:
711 info.si_signo = TARGET_SIGSEGV; 711 info.si_signo = TARGET_SIGSEGV;
712 info.si_errno = 0; 712 info.si_errno = 0;
713 info.si_code = TARGET_SEGV_MAPERR; 713 info.si_code = TARGET_SEGV_MAPERR;
714 break; 714 break;
715 - case EXCP_DSI_NOTSUP:  
716 - case EXCP_DSI_EXTERNAL: 715 + case 0x04000000:
717 info.si_signo = TARGET_SIGILL; 716 info.si_signo = TARGET_SIGILL;
718 info.si_errno = 0; 717 info.si_errno = 0;
719 info.si_code = TARGET_ILL_ILLADR; 718 info.si_code = TARGET_ILL_ILLADR;
720 break; 719 break;
721 - case EXCP_DSI_PROT: 720 + case 0x08000000:
722 info.si_signo = TARGET_SIGSEGV; 721 info.si_signo = TARGET_SIGSEGV;
723 info.si_errno = 0; 722 info.si_errno = 0;
724 info.si_code = TARGET_SEGV_ACCERR; 723 info.si_code = TARGET_SEGV_ACCERR;
725 break; 724 break;
726 - case EXCP_DSI_DABR:  
727 - info.si_signo = TARGET_SIGTRAP;  
728 - info.si_errno = 0;  
729 - info.si_code = TARGET_TRAP_BRKPT;  
730 - break;  
731 default: 725 default:
732 /* Let's send a regular segfault... */ 726 /* Let's send a regular segfault... */
733 fprintf(stderr, "Invalid segfault errno (%02x)\n", 727 fprintf(stderr, "Invalid segfault errno (%02x)\n",
@@ -748,19 +742,14 @@ void cpu_loop(CPUPPCState *env) @@ -748,19 +742,14 @@ void cpu_loop(CPUPPCState *env)
748 fprintf(stderr, "Invalid instruction fetch\n"); 742 fprintf(stderr, "Invalid instruction fetch\n");
749 if (loglevel) 743 if (loglevel)
750 fprintf(logfile, "Invalid instruction fetch\n"); 744 fprintf(logfile, "Invalid instruction fetch\n");
751 - switch (env->error_code) {  
752 - case EXCP_ISI_TRANSLATE: 745 + switch (env->error_code & 0xFF000000) {
  746 + case 0x40000000:
753 info.si_signo = TARGET_SIGSEGV; 747 info.si_signo = TARGET_SIGSEGV;
754 info.si_errno = 0; 748 info.si_errno = 0;
755 info.si_code = TARGET_SEGV_MAPERR; 749 info.si_code = TARGET_SEGV_MAPERR;
756 break; 750 break;
757 - case EXCP_ISI_GUARD:  
758 - info.si_signo = TARGET_SIGILL;  
759 - info.si_errno = 0;  
760 - info.si_code = TARGET_ILL_ILLADR;  
761 - break;  
762 - case EXCP_ISI_NOEXEC:  
763 - case EXCP_ISI_PROT: 751 + case 0x10000000:
  752 + case 0x08000000:
764 info.si_signo = TARGET_SIGSEGV; 753 info.si_signo = TARGET_SIGSEGV;
765 info.si_errno = 0; 754 info.si_errno = 0;
766 info.si_code = TARGET_SEGV_ACCERR; 755 info.si_code = TARGET_SEGV_ACCERR;
@@ -930,18 +919,6 @@ void cpu_loop(CPUPPCState *env) @@ -930,18 +919,6 @@ void cpu_loop(CPUPPCState *env)
930 if (loglevel) 919 if (loglevel)
931 fprintf(logfile, "Decrementer exception\n"); 920 fprintf(logfile, "Decrementer exception\n");
932 abort(); 921 abort();
933 - case EXCP_RESA: /* Implementation specific */  
934 - /* Should not happen ! */  
935 - fprintf(stderr, "RESA exception should never happen !\n");  
936 - if (loglevel)  
937 - fprintf(logfile, "RESA exception should never happen !\n");  
938 - abort();  
939 - case EXCP_RESB: /* Implementation specific */  
940 - /* Should not happen ! */  
941 - fprintf(stderr, "RESB exception should never happen !\n");  
942 - if (loglevel)  
943 - fprintf(logfile, "RESB exception should never happen !\n");  
944 - abort();  
945 case EXCP_TRACE: 922 case EXCP_TRACE:
946 /* Do nothing: we use this to trace execution */ 923 /* Do nothing: we use this to trace execution */
947 break; 924 break;
@@ -963,12 +940,6 @@ void cpu_loop(CPUPPCState *env) @@ -963,12 +940,6 @@ void cpu_loop(CPUPPCState *env)
963 case EXCP_BRANCH: 940 case EXCP_BRANCH:
964 /* We stopped because of a jump... */ 941 /* We stopped because of a jump... */
965 break; 942 break;
966 - case EXCP_RFI:  
967 - /* Should not occur: we always are in user mode */  
968 - fprintf(stderr, "Return from interrupt ?\n");  
969 - if (loglevel)  
970 - fprintf(logfile, "Return from interrupt ?\n");  
971 - abort();  
972 case EXCP_INTERRUPT: 943 case EXCP_INTERRUPT:
973 /* Don't know why this should ever happen... */ 944 /* Don't know why this should ever happen... */
974 break; 945 break;
target-ppc/cpu.h
@@ -924,62 +924,72 @@ enum { @@ -924,62 +924,72 @@ enum {
924 924
925 /*****************************************************************************/ 925 /*****************************************************************************/
926 /* Exceptions */ 926 /* Exceptions */
927 -enum {  
928 - EXCP_NONE = -1,  
929 - /* PowerPC hardware exceptions : exception vector / 0x100 */  
930 - EXCP_RESET = 0x01, /* System reset */  
931 - EXCP_MACHINE_CHECK = 0x02, /* Machine check exception */  
932 - EXCP_DSI = 0x03, /* Impossible memory access */  
933 - EXCP_ISI = 0x04, /* Impossible instruction fetch */  
934 - EXCP_EXTERNAL = 0x05, /* External interruption */  
935 - EXCP_ALIGN = 0x06, /* Alignment exception */  
936 - EXCP_PROGRAM = 0x07, /* Program exception */  
937 - EXCP_NO_FP = 0x08, /* No floating point */  
938 - EXCP_DECR = 0x09, /* Decrementer exception */  
939 - EXCP_RESA = 0x0A, /* Implementation specific */  
940 - EXCP_RESB = 0x0B, /* Implementation specific */  
941 - EXCP_SYSCALL = 0x0C, /* System call */  
942 - EXCP_TRACE = 0x0D, /* Trace exception (optional) */  
943 - EXCP_FP_ASSIST = 0x0E, /* Floating-point assist (optional) */  
944 - /* MPC740/745/750 & IBM 750 */  
945 - EXCP_PERF = 0x0F, /* Performance monitor */  
946 - EXCP_IABR = 0x13, /* Instruction address breakpoint */  
947 - EXCP_SMI = 0x14, /* System management interrupt */  
948 - EXCP_THRM = 0x15, /* Thermal management interrupt */  
949 - /* MPC755 */  
950 - EXCP_TLBMISS = 0x10, /* Instruction TLB miss */  
951 - EXCP_TLBMISS_DL = 0x11, /* Data TLB miss for load */  
952 - EXCP_TLBMISS_DS = 0x12, /* Data TLB miss for store */  
953 - EXCP_PPC_MAX = 0x16,  
954 - /* Qemu exception */  
955 - EXCP_OFCALL = 0x20, /* Call open-firmware emulator */  
956 - EXCP_RTASCALL = 0x21, /* Call RTAS emulator */  
957 - /* Special cases where we want to stop translation */  
958 - EXCP_MTMSR = 0x104, /* mtmsr instruction: */ 927 +#define EXCP_NONE -1
  928 +/* PowerPC hardware exceptions : exception vectors defined in PowerPC book 3 */
  929 +#define EXCP_RESET 0x0100 /* System reset */
  930 +#define EXCP_MACHINE_CHECK 0x0200 /* Machine check exception */
  931 +#define EXCP_DSI 0x0300 /* Data storage exception */
  932 +#define EXCP_DSEG 0x0380 /* Data segment exception */
  933 +#define EXCP_ISI 0x0400 /* Instruction storage exception */
  934 +#define EXCP_ISEG 0x0480 /* Instruction segment exception */
  935 +#define EXCP_EXTERNAL 0x0500 /* External interruption */
  936 +#define EXCP_ALIGN 0x0600 /* Alignment exception */
  937 +#define EXCP_PROGRAM 0x0700 /* Program exception */
  938 +#define EXCP_NO_FP 0x0800 /* Floating point unavailable exception */
  939 +#define EXCP_DECR 0x0900 /* Decrementer exception */
  940 +#define EXCP_HDECR 0x0980 /* Hypervisor decrementer exception */
  941 +#define EXCP_SYSCALL 0x0C00 /* System call */
  942 +#define EXCP_TRACE 0x0D00 /* Trace exception */
  943 +#define EXCP_PERF 0x0F00 /* Performance monitor exception */
  944 +/* Exceptions defined in PowerPC 32 bits programming environment manual */
  945 +#define EXCP_FP_ASSIST 0x0E00 /* Floating-point assist */
  946 +/* Implementation specific exceptions */
  947 +/* 40x exceptions */
  948 +#define EXCP_40x_PIT 0x1000 /* Programmable interval timer interrupt */
  949 +#define EXCP_40x_FIT 0x1010 /* Fixed interval timer interrupt */
  950 +#define EXCP_40x_WATCHDOG 0x1020 /* Watchdog timer exception */
  951 +#define EXCP_40x_DTLBMISS 0x1100 /* Data TLB miss exception */
  952 +#define EXCP_40x_ITLBMISS 0x1200 /* Instruction TLB miss exception */
  953 +#define EXCP_40x_DEBUG 0x2000 /* Debug exception */
  954 +/* 405 specific exceptions */
  955 +#define EXCP_405_APU 0x0F20 /* APU unavailable exception */
  956 +/* TLB assist exceptions (602/603) */
  957 +#define EXCP_I_TLBMISS 0x1000 /* Instruction TLB miss */
  958 +#define EXCP_DL_TLBMISS 0x1100 /* Data load TLB miss */
  959 +#define EXCP_DS_TLBMISS 0x1200 /* Data store TLB miss */
  960 +/* Breakpoint exceptions (602/603/604/620/740/745/750/755...) */
  961 +#define EXCP_IABR 0x1300 /* Instruction address breakpoint */
  962 +#define EXCP_SMI 0x1400 /* System management interrupt */
  963 +/* Altivec related exceptions */
  964 +#define EXCP_VPU 0x0F20 /* VPU unavailable exception */
  965 +/* 601 specific exceptions */
  966 +#define EXCP_601_IO 0x0600 /* IO error exception */
  967 +#define EXCP_601_RUNM 0x2000 /* Run mode exception */
  968 +/* 602 specific exceptions */
  969 +#define EXCP_602_WATCHDOG 0x1500 /* Watchdog exception */
  970 +#define EXCP_602_EMUL 0x1600 /* Emulation trap exception */
  971 +/* G2 specific exceptions */
  972 +#define EXCP_G2_CRIT 0x0A00 /* Critical interrupt */
  973 +/* MPC740/745/750 & IBM 750 specific exceptions */
  974 +#define EXCP_THRM 0x1700 /* Thermal management interrupt */
  975 +/* 74xx specific exceptions */
  976 +#define EXCP_74xx_VPUA 0x1600 /* VPU assist exception */
  977 +/* 970FX specific exceptions */
  978 +#define EXCP_970_SOFTP 0x1500 /* Soft patch exception */
  979 +#define EXCP_970_MAINT 0x1600 /* Maintenance exception */
  980 +#define EXCP_970_THRM 0x1800 /* Thermal exception */
  981 +#define EXCP_970_VPUA 0x1700 /* VPU assist exception */
  982 +/* End of exception vectors area */
  983 +#define EXCP_PPC_MAX 0x4000
  984 +/* Qemu exceptions: special cases we want to stop translation */
  985 +#define EXCP_MTMSR 0x11000 /* mtmsr instruction: */
959 /* may change privilege level */ 986 /* may change privilege level */
960 - EXCP_BRANCH = 0x108, /* branch instruction */  
961 - EXCP_RFI = 0x10C, /* return from interrupt */  
962 - EXCP_SYSCALL_USER = 0x110, /* System call in user mode only */  
963 -}; 987 +#define EXCP_BRANCH 0x11001 /* branch instruction */
  988 +#define EXCP_SYSCALL_USER 0x12000 /* System call in user mode only */
  989 +#define EXCP_INTERRUPT_CRITICAL 0x13000 /* critical IRQ */
  990 +
964 /* Error codes */ 991 /* Error codes */
965 enum { 992 enum {
966 - /* Exception subtypes for EXCP_DSI */  
967 - EXCP_DSI_TRANSLATE = 0x01, /* Data address can't be translated */  
968 - EXCP_DSI_NOTSUP = 0x02, /* Access type not supported */  
969 - EXCP_DSI_PROT = 0x03, /* Memory protection violation */  
970 - EXCP_DSI_EXTERNAL = 0x04, /* External access disabled */  
971 - EXCP_DSI_DABR = 0x05, /* Data address breakpoint */  
972 - /* flags for EXCP_DSI */  
973 - EXCP_DSI_DIRECT = 0x10,  
974 - EXCP_DSI_STORE = 0x20,  
975 - EXCP_DSI_ECXW = 0x40,  
976 - /* Exception subtypes for EXCP_ISI */  
977 - EXCP_ISI_TRANSLATE = 0x01, /* Code address can't be translated */  
978 - EXCP_ISI_NOEXEC = 0x02, /* Try to fetch from a data segment */  
979 - EXCP_ISI_GUARD = 0x03, /* Fetch from guarded memory */  
980 - EXCP_ISI_PROT = 0x04, /* Memory protection violation */  
981 - EXCP_ISI_DIRECT = 0x05, /* Trying to fetch from *  
982 - * a direct store segment */  
983 /* Exception subtypes for EXCP_ALIGN */ 993 /* Exception subtypes for EXCP_ALIGN */
984 EXCP_ALIGN_FP = 0x01, /* FP alignment exception */ 994 EXCP_ALIGN_FP = 0x01, /* FP alignment exception */
985 EXCP_ALIGN_LST = 0x02, /* Unaligned mult/extern load/store */ 995 EXCP_ALIGN_LST = 0x02, /* Unaligned mult/extern load/store */
target-ppc/helper.c
@@ -22,8 +22,6 @@ @@ -22,8 +22,6 @@
22 //#define DEBUG_MMU 22 //#define DEBUG_MMU
23 //#define DEBUG_BATS 23 //#define DEBUG_BATS
24 //#define DEBUG_EXCEPTIONS 24 //#define DEBUG_EXCEPTIONS
25 -/* accurate but slower TLB flush in exceptions */  
26 -//#define ACCURATE_TLB_FLUSH  
27 25
28 /*****************************************************************************/ 26 /*****************************************************************************/
29 /* PowerPC MMU emulation */ 27 /* PowerPC MMU emulation */
@@ -524,20 +522,25 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -524,20 +522,25 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
524 switch (ret) { 522 switch (ret) {
525 case -1: 523 case -1:
526 /* No matches in page tables */ 524 /* No matches in page tables */
527 - error_code = EXCP_ISI_TRANSLATE; 525 + error_code = 0x40000000;
528 break; 526 break;
529 case -2: 527 case -2:
530 /* Access rights violation */ 528 /* Access rights violation */
531 - error_code = EXCP_ISI_PROT; 529 + error_code = 0x08000000;
532 break; 530 break;
533 case -3: 531 case -3:
534 /* No execute protection violation */ 532 /* No execute protection violation */
535 - error_code = EXCP_ISI_NOEXEC; 533 + error_code = 0x10000000;
536 break; 534 break;
537 case -4: 535 case -4:
538 /* Direct store exception */ 536 /* Direct store exception */
539 /* No code fetch is allowed in direct-store areas */ 537 /* No code fetch is allowed in direct-store areas */
540 - error_code = EXCP_ISI_DIRECT; 538 + error_code = 0x10000000;
  539 + break;
  540 + case -5:
  541 + /* No match in segment table */
  542 + exception = EXCP_ISEG;
  543 + error_code = 0;
541 break; 544 break;
542 } 545 }
543 } else { 546 } else {
@@ -545,11 +548,11 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -545,11 +548,11 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
545 switch (ret) { 548 switch (ret) {
546 case -1: 549 case -1:
547 /* No matches in page tables */ 550 /* No matches in page tables */
548 - error_code = EXCP_DSI_TRANSLATE; 551 + error_code = 0x40000000;
549 break; 552 break;
550 case -2: 553 case -2:
551 /* Access rights violation */ 554 /* Access rights violation */
552 - error_code = EXCP_DSI_PROT; 555 + error_code = 0x08000000;
553 break; 556 break;
554 case -4: 557 case -4:
555 /* Direct store exception */ 558 /* Direct store exception */
@@ -561,14 +564,11 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -561,14 +564,11 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
561 break; 564 break;
562 case ACCESS_RES: 565 case ACCESS_RES:
563 /* lwarx, ldarx or srwcx. */ 566 /* lwarx, ldarx or srwcx. */
564 - exception = EXCP_DSI;  
565 - error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT; 567 + error_code = 0x04000000;
566 break; 568 break;
567 case ACCESS_EXT: 569 case ACCESS_EXT:
568 /* eciwx or ecowx */ 570 /* eciwx or ecowx */
569 - exception = EXCP_DSI;  
570 - error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT |  
571 - EXCP_DSI_ECXW; 571 + error_code = 0x04100000;
572 break; 572 break;
573 default: 573 default:
574 printf("DSI: invalid exception (%d)\n", ret); 574 printf("DSI: invalid exception (%d)\n", ret);
@@ -576,11 +576,17 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -576,11 +576,17 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
576 error_code = EXCP_INVAL | EXCP_INVAL_INVAL; 576 error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
577 break; 577 break;
578 } 578 }
  579 + case -5:
  580 + /* No match in segment table */
  581 + exception = EXCP_DSEG;
  582 + error_code = 0;
  583 + break;
579 } 584 }
580 if (rw) 585 if (rw)
581 - error_code |= EXCP_DSI_STORE; 586 + error_code |= 0x02000000;
582 /* Store fault address */ 587 /* Store fault address */
583 env->spr[SPR_DAR] = address; 588 env->spr[SPR_DAR] = address;
  589 + env->spr[SPR_DSISR] = error_code;
584 } 590 }
585 #if 0 591 #if 0
586 printf("%s: set exception to %d %02x\n", 592 printf("%s: set exception to %d %02x\n",
@@ -985,119 +991,107 @@ static void dump_syscall(CPUState *env) @@ -985,119 +991,107 @@ static void dump_syscall(CPUState *env)
985 991
986 void do_interrupt (CPUState *env) 992 void do_interrupt (CPUState *env)
987 { 993 {
988 - uint32_t msr; 994 + target_ulong msr, *srr_0, *srr_1, tmp;
989 int excp; 995 int excp;
990 996
991 excp = env->exception_index; 997 excp = env->exception_index;
992 msr = do_load_msr(env); 998 msr = do_load_msr(env);
  999 + /* The default is to use SRR0 & SRR1 to save the exception context */
  1000 + srr_0 = &env->spr[SPR_SRR0];
  1001 + srr_1 = &env->spr[SPR_SRR1];
993 #if defined (DEBUG_EXCEPTIONS) 1002 #if defined (DEBUG_EXCEPTIONS)
994 - if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1)  
995 - {  
996 - if (loglevel > 0) {  
997 - fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",  
998 - env->nip, excp << 8, env->error_code); 1003 + if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) {
  1004 + if (loglevel != 0) {
  1005 + fprintf(logfile, "Raise exception at 0x%08lx => 0x%08x (%02x)\n",
  1006 + (unsigned long)env->nip, excp, env->error_code);
  1007 + cpu_dump_state(env, logfile, fprintf, 0);
999 } 1008 }
1000 - if (loglevel > 0)  
1001 - cpu_dump_state(env, logfile, fprintf, 0);  
1002 } 1009 }
1003 #endif 1010 #endif
1004 if (loglevel & CPU_LOG_INT) { 1011 if (loglevel & CPU_LOG_INT) {
1005 - fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",  
1006 - env->nip, excp << 8, env->error_code); 1012 + fprintf(logfile, "Raise exception at 0x%08lx => 0x%08x (%02x)\n",
  1013 + (unsigned long)env->nip, excp, env->error_code);
1007 } 1014 }
  1015 + msr_pow = 0;
1008 /* Generate informations in save/restore registers */ 1016 /* Generate informations in save/restore registers */
1009 switch (excp) { 1017 switch (excp) {
1010 - case EXCP_NONE:  
1011 - /* Do nothing */  
1012 -#if defined (DEBUG_EXCEPTIONS)  
1013 - printf("%s: escape EXCP_NONE\n", __func__);  
1014 -#endif  
1015 - return;  
1016 - case EXCP_RESET:  
1017 - if (msr_ip)  
1018 - excp += 0xFFC00; 1018 + /* Generic PowerPC exceptions */
  1019 + case EXCP_RESET: /* 0x0100 */
  1020 + if (PPC_EXCP(env) != PPC_FLAGS_EXCP_40x) {
  1021 + if (msr_ip)
  1022 + excp += 0xFFC00;
  1023 + excp |= 0xFFC00000;
  1024 + } else {
  1025 + srr_0 = &env->spr[SPR_40x_SRR2];
  1026 + srr_1 = &env->spr[SPR_40x_SRR3];
  1027 + }
1019 goto store_next; 1028 goto store_next;
1020 - case EXCP_MACHINE_CHECK: 1029 + case EXCP_MACHINE_CHECK: /* 0x0200 */
1021 if (msr_me == 0) { 1030 if (msr_me == 0) {
1022 cpu_abort(env, "Machine check exception while not allowed\n"); 1031 cpu_abort(env, "Machine check exception while not allowed\n");
1023 } 1032 }
  1033 + if (PPC_EXCP(env) == PPC_FLAGS_EXCP_40x) {
  1034 + srr_0 = &env->spr[SPR_40x_SRR2];
  1035 + srr_1 = &env->spr[SPR_40x_SRR3];
  1036 + }
1024 msr_me = 0; 1037 msr_me = 0;
1025 break; 1038 break;
1026 - case EXCP_DSI: 1039 + case EXCP_DSI: /* 0x0300 */
1027 /* Store exception cause */ 1040 /* Store exception cause */
1028 /* data location address has been stored 1041 /* data location address has been stored
1029 * when the fault has been detected 1042 * when the fault has been detected
1030 - */ 1043 + */
1031 msr &= ~0xFFFF0000; 1044 msr &= ~0xFFFF0000;
1032 - env->spr[SPR_DSISR] = 0;  
1033 - if ((env->error_code & 0x0f) == EXCP_DSI_TRANSLATE)  
1034 - env->spr[SPR_DSISR] |= 0x40000000;  
1035 - else if ((env->error_code & 0x0f) == EXCP_DSI_PROT)  
1036 - env->spr[SPR_DSISR] |= 0x08000000;  
1037 - else if ((env->error_code & 0x0f) == EXCP_DSI_NOTSUP) {  
1038 - env->spr[SPR_DSISR] |= 0x80000000;  
1039 - if (env->error_code & EXCP_DSI_DIRECT)  
1040 - env->spr[SPR_DSISR] |= 0x04000000;  
1041 - }  
1042 - if (env->error_code & EXCP_DSI_STORE)  
1043 - env->spr[SPR_DSISR] |= 0x02000000;  
1044 - if ((env->error_code & 0xF) == EXCP_DSI_DABR)  
1045 - env->spr[SPR_DSISR] |= 0x00400000;  
1046 - if (env->error_code & EXCP_DSI_ECXW)  
1047 - env->spr[SPR_DSISR] |= 0x00100000;  
1048 #if defined (DEBUG_EXCEPTIONS) 1045 #if defined (DEBUG_EXCEPTIONS)
1049 if (loglevel) { 1046 if (loglevel) {
1050 fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n", 1047 fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
1051 env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1048 env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1052 } else { 1049 } else {
1053 - printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",  
1054 - env->spr[SPR_DSISR], env->spr[SPR_DAR], env->nip); 1050 + printf("DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
  1051 + env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1055 } 1052 }
1056 #endif 1053 #endif
1057 goto store_next; 1054 goto store_next;
1058 - case EXCP_ISI: 1055 + case EXCP_ISI: /* 0x0400 */
1059 /* Store exception cause */ 1056 /* Store exception cause */
1060 msr &= ~0xFFFF0000; 1057 msr &= ~0xFFFF0000;
1061 - if (env->error_code == EXCP_ISI_TRANSLATE)  
1062 - msr |= 0x40000000;  
1063 - else if (env->error_code == EXCP_ISI_NOEXEC ||  
1064 - env->error_code == EXCP_ISI_GUARD ||  
1065 - env->error_code == EXCP_ISI_DIRECT)  
1066 - msr |= 0x10000000;  
1067 - else  
1068 - msr |= 0x08000000; 1058 + msr |= env->error_code;
1069 #if defined (DEBUG_EXCEPTIONS) 1059 #if defined (DEBUG_EXCEPTIONS)
1070 - if (loglevel) { 1060 + if (loglevel != 0) {
1071 fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n", 1061 fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",
1072 msr, env->nip); 1062 msr, env->nip);
1073 - } else {  
1074 - printf("ISI exception: msr=0x%08x, nip=0x%08x tbl:0x%08x\n",  
1075 - msr, env->nip, env->spr[V_TBL]);  
1076 } 1063 }
1077 #endif 1064 #endif
1078 goto store_next; 1065 goto store_next;
1079 - case EXCP_EXTERNAL: 1066 + case EXCP_EXTERNAL: /* 0x0500 */
1080 if (msr_ee == 0) { 1067 if (msr_ee == 0) {
1081 #if defined (DEBUG_EXCEPTIONS) 1068 #if defined (DEBUG_EXCEPTIONS)
1082 if (loglevel > 0) { 1069 if (loglevel > 0) {
1083 fprintf(logfile, "Skipping hardware interrupt\n"); 1070 fprintf(logfile, "Skipping hardware interrupt\n");
1084 - } 1071 + }
1085 #endif 1072 #endif
1086 /* Requeue it */ 1073 /* Requeue it */
1087 - do_raise_exception(EXCP_EXTERNAL); 1074 + env->interrupt_request |= CPU_INTERRUPT_HARD;
1088 return; 1075 return;
1089 - } 1076 + }
1090 goto store_next; 1077 goto store_next;
1091 - case EXCP_ALIGN:  
1092 - /* Store exception cause */  
1093 - /* Get rS/rD and rA from faulting opcode */  
1094 - env->spr[SPR_DSISR] |=  
1095 - (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;  
1096 - /* data location address has been stored  
1097 - * when the fault has been detected  
1098 - */ 1078 + case EXCP_ALIGN: /* 0x0600 */
  1079 + if (PPC_EXCP(env) != PPC_FLAGS_EXCP_601) {
  1080 + /* Store exception cause */
  1081 + /* Get rS/rD and rA from faulting opcode */
  1082 + env->spr[SPR_DSISR] |=
  1083 + (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
  1084 + /* data location address has been stored
  1085 + * when the fault has been detected
  1086 + */
  1087 + } else {
  1088 + /* IO error exception on PowerPC 601 */
  1089 + /* XXX: TODO */
  1090 + cpu_abort(env,
  1091 + "601 IO error exception is not implemented yet !\n");
  1092 + }
1099 goto store_current; 1093 goto store_current;
1100 - case EXCP_PROGRAM: 1094 + case EXCP_PROGRAM: /* 0x0700 */
1101 msr &= ~0xFFFF0000; 1095 msr &= ~0xFFFF0000;
1102 switch (env->error_code & ~0xF) { 1096 switch (env->error_code & ~0xF) {
1103 case EXCP_FP: 1097 case EXCP_FP:
@@ -1131,17 +1125,19 @@ void do_interrupt (CPUState *env) @@ -1131,17 +1125,19 @@ void do_interrupt (CPUState *env)
1131 } 1125 }
1132 msr |= 0x00010000; 1126 msr |= 0x00010000;
1133 goto store_current; 1127 goto store_current;
1134 - case EXCP_NO_FP: 1128 + case EXCP_NO_FP: /* 0x0800 */
1135 msr &= ~0xFFFF0000; 1129 msr &= ~0xFFFF0000;
1136 goto store_current; 1130 goto store_current;
1137 case EXCP_DECR: 1131 case EXCP_DECR:
1138 if (msr_ee == 0) { 1132 if (msr_ee == 0) {
  1133 +#if 1
1139 /* Requeue it */ 1134 /* Requeue it */
1140 - do_raise_exception(EXCP_DECR); 1135 + env->interrupt_request |= CPU_INTERRUPT_TIMER;
  1136 +#endif
1141 return; 1137 return;
1142 } 1138 }
1143 goto store_next; 1139 goto store_next;
1144 - case EXCP_SYSCALL: 1140 + case EXCP_SYSCALL: /* 0x0C00 */
1145 /* NOTE: this is a temporary hack to support graphics OSI 1141 /* NOTE: this is a temporary hack to support graphics OSI
1146 calls from the MOL driver */ 1142 calls from the MOL driver */
1147 if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b && 1143 if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
@@ -1153,35 +1149,332 @@ void do_interrupt (CPUState *env) @@ -1153,35 +1149,332 @@ void do_interrupt (CPUState *env)
1153 dump_syscall(env); 1149 dump_syscall(env);
1154 } 1150 }
1155 goto store_next; 1151 goto store_next;
1156 - case EXCP_TRACE: 1152 + case EXCP_TRACE: /* 0x0D00 */
  1153 + /* XXX: TODO */
  1154 + cpu_abort(env, "Trace exception is not implemented yet !\n");
  1155 + goto store_next;
  1156 + case EXCP_PERF: /* 0x0F00 */
  1157 + /* XXX: TODO */
  1158 + cpu_abort(env,
  1159 + "Performance counter exception is not implemented yet !\n");
  1160 + goto store_next;
  1161 + /* 32 bits PowerPC specific exceptions */
  1162 + case EXCP_FP_ASSIST: /* 0x0E00 */
  1163 + /* XXX: TODO */
  1164 + cpu_abort(env, "Floating point assist exception "
  1165 + "is not implemented yet !\n");
  1166 + goto store_next;
  1167 + /* 64 bits PowerPC exceptions */
  1168 + case EXCP_DSEG: /* 0x0380 */
  1169 + /* XXX: TODO */
  1170 + cpu_abort(env, "Data segment exception is not implemented yet !\n");
1157 goto store_next; 1171 goto store_next;
1158 - case EXCP_FP_ASSIST: 1172 + case EXCP_ISEG: /* 0x0480 */
  1173 + /* XXX: TODO */
  1174 + cpu_abort(env,
  1175 + "Instruction segment exception is not implemented yet !\n");
1159 goto store_next; 1176 goto store_next;
1160 - case EXCP_MTMSR:  
1161 - /* Nothing to do */ 1177 + case EXCP_HDECR: /* 0x0980 */
  1178 + if (msr_ee == 0) {
  1179 +#if 1
  1180 + /* Requeue it */
  1181 + env->interrupt_request |= CPU_INTERRUPT_TIMER;
  1182 +#endif
1162 return; 1183 return;
1163 - case EXCP_BRANCH:  
1164 - /* Nothing to do */ 1184 + }
  1185 + cpu_abort(env,
  1186 + "Hypervisor decrementer exception is not implemented yet !\n");
  1187 + goto store_next;
  1188 + /* Implementation specific exceptions */
  1189 + case 0x0A00:
  1190 + if (PPC_EXCP(env) != PPC_FLAGS_EXCP_602) {
  1191 + /* Critical interrupt on G2 */
  1192 + /* XXX: TODO */
  1193 + cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");
  1194 + goto store_next;
  1195 + } else {
  1196 + cpu_abort(env, "Invalid exception 0x0A00 !\n");
  1197 + }
1165 return; 1198 return;
1166 - case EXCP_RFI:  
1167 - /* Restore user-mode state */  
1168 -#if defined (DEBUG_EXCEPTIONS)  
1169 - if (msr_pr == 1)  
1170 - printf("Return from exception => 0x%08x\n", (uint32_t)env->nip); 1199 + case 0x0F20:
  1200 + switch (PPC_EXCP(env)) {
  1201 + case PPC_FLAGS_EXCP_40x:
  1202 + /* APU unavailable on 405 */
  1203 + /* XXX: TODO */
  1204 + cpu_abort(env,
  1205 + "APU unavailable exception is not implemented yet !\n");
  1206 + goto store_next;
  1207 + case PPC_FLAGS_EXCP_74xx:
  1208 + /* Altivec unavailable */
  1209 + /* XXX: TODO */
  1210 + cpu_abort(env, "Altivec unavailable exception "
  1211 + "is not implemented yet !\n");
  1212 + goto store_next;
  1213 + default:
  1214 + cpu_abort(env, "Invalid exception 0x0F20 !\n");
  1215 + break;
  1216 + }
  1217 + return;
  1218 + case 0x1000:
  1219 + switch (PPC_EXCP(env)) {
  1220 + case PPC_FLAGS_EXCP_40x:
  1221 + /* PIT on 4xx */
  1222 + /* XXX: TODO */
  1223 + cpu_abort(env, "40x PIT exception is not implemented yet !\n");
  1224 + goto store_next;
  1225 + case PPC_FLAGS_EXCP_602:
  1226 + case PPC_FLAGS_EXCP_603:
  1227 + /* ITLBMISS on 602/603 */
  1228 + msr &= ~0xF00F0000;
  1229 + msr_tgpr = 1;
  1230 + goto store_gprs;
  1231 + default:
  1232 + cpu_abort(env, "Invalid exception 0x1000 !\n");
  1233 + break;
  1234 + }
  1235 + return;
  1236 + case 0x1010:
  1237 + switch (PPC_EXCP(env)) {
  1238 + case PPC_FLAGS_EXCP_40x:
  1239 + /* FIT on 4xx */
  1240 + cpu_abort(env, "40x FIT exception is not implemented yet !\n");
  1241 + /* XXX: TODO */
  1242 + goto store_next;
  1243 + default:
  1244 + cpu_abort(env, "Invalid exception 0x1010 !\n");
  1245 + break;
  1246 + }
  1247 + return;
  1248 + case 0x1020:
  1249 + switch (PPC_EXCP(env)) {
  1250 + case PPC_FLAGS_EXCP_40x:
  1251 + /* Watchdog on 4xx */
  1252 + /* XXX: TODO */
  1253 + cpu_abort(env,
  1254 + "40x watchdog exception is not implemented yet !\n");
  1255 + goto store_next;
  1256 + default:
  1257 + cpu_abort(env, "Invalid exception 0x1020 !\n");
  1258 + break;
  1259 + }
  1260 + return;
  1261 + case 0x1100:
  1262 + switch (PPC_EXCP(env)) {
  1263 + case PPC_FLAGS_EXCP_40x:
  1264 + /* DTLBMISS on 4xx */
  1265 + /* XXX: TODO */
  1266 + cpu_abort(env,
  1267 + "40x DTLBMISS exception is not implemented yet !\n");
  1268 + goto store_next;
  1269 + case PPC_FLAGS_EXCP_602:
  1270 + case PPC_FLAGS_EXCP_603:
  1271 + /* DLTLBMISS on 602/603 */
  1272 + msr &= ~0xF00F0000;
  1273 + msr_tgpr = 1;
  1274 + goto store_gprs;
  1275 + default:
  1276 + cpu_abort(env, "Invalid exception 0x1100 !\n");
  1277 + break;
  1278 + }
  1279 + return;
  1280 + case 0x1200:
  1281 + switch (PPC_EXCP(env)) {
  1282 + case PPC_FLAGS_EXCP_40x:
  1283 + /* ITLBMISS on 4xx */
  1284 + /* XXX: TODO */
  1285 + cpu_abort(env,
  1286 + "40x ITLBMISS exception is not implemented yet !\n");
  1287 + goto store_next;
  1288 + case PPC_FLAGS_EXCP_602:
  1289 + case PPC_FLAGS_EXCP_603:
  1290 + /* DSTLBMISS on 602/603 */
  1291 + msr &= ~0xF00F0000;
  1292 + msr_tgpr = 1;
  1293 + store_gprs:
  1294 +#if defined (DEBUG_SOFTWARE_TLB)
  1295 + if (loglevel != 0) {
  1296 + fprintf(logfile, "6xx %sTLB miss: IM %08x DM %08x IC %08x "
  1297 + "DC %08x H1 %08x H2 %08x %08x\n",
  1298 + excp == 0x1000 ? "I" : excp == 0x1100 ? "DL" : "DS",
  1299 + env->spr[SPR_IMISS], env->spr[SPR_DMISS],
  1300 + env->spr[SPR_ICMP], env->spr[SPR_DCMP],
  1301 + env->spr[SPR_DHASH1], env->spr[SPR_DHASH2],
  1302 + env->error_code);
  1303 + }
1171 #endif 1304 #endif
  1305 + /* Swap temporary saved registers with GPRs */
  1306 + tmp = env->gpr[0];
  1307 + env->gpr[0] = env->tgpr[0];
  1308 + env->tgpr[0] = tmp;
  1309 + tmp = env->gpr[1];
  1310 + env->gpr[1] = env->tgpr[1];
  1311 + env->tgpr[1] = tmp;
  1312 + tmp = env->gpr[2];
  1313 + env->gpr[2] = env->tgpr[2];
  1314 + env->tgpr[2] = tmp;
  1315 + tmp = env->gpr[3];
  1316 + env->gpr[3] = env->tgpr[3];
  1317 + env->tgpr[3] = tmp;
  1318 + msr |= env->crf[0] << 28;
  1319 + msr |= env->error_code; /* key, D/I, S/L bits */
  1320 + /* Set way using a LRU mechanism */
  1321 + msr |= (env->last_way ^ 1) << 17;
  1322 + goto store_next;
  1323 + default:
  1324 + cpu_abort(env, "Invalid exception 0x1200 !\n");
  1325 + break;
  1326 + }
  1327 + return;
  1328 + case 0x1300:
  1329 + switch (PPC_EXCP(env)) {
  1330 + case PPC_FLAGS_EXCP_601:
  1331 + case PPC_FLAGS_EXCP_602:
  1332 + case PPC_FLAGS_EXCP_603:
  1333 + case PPC_FLAGS_EXCP_604:
  1334 + case PPC_FLAGS_EXCP_7x0:
  1335 + case PPC_FLAGS_EXCP_7x5:
  1336 + /* IABR on 6xx/7xx */
  1337 + /* XXX: TODO */
  1338 + cpu_abort(env, "IABR exception is not implemented yet !\n");
  1339 + goto store_next;
  1340 + default:
  1341 + cpu_abort(env, "Invalid exception 0x1300 !\n");
  1342 + break;
  1343 + }
  1344 + return;
  1345 + case 0x1400:
  1346 + switch (PPC_EXCP(env)) {
  1347 + case PPC_FLAGS_EXCP_601:
  1348 + case PPC_FLAGS_EXCP_602:
  1349 + case PPC_FLAGS_EXCP_603:
  1350 + case PPC_FLAGS_EXCP_604:
  1351 + case PPC_FLAGS_EXCP_7x0:
  1352 + case PPC_FLAGS_EXCP_7x5:
  1353 + /* SMI on 6xx/7xx */
  1354 + /* XXX: TODO */
  1355 + cpu_abort(env, "SMI exception is not implemented yet !\n");
  1356 + goto store_next;
  1357 + default:
  1358 + cpu_abort(env, "Invalid exception 0x1400 !\n");
  1359 + break;
  1360 + }
  1361 + return;
  1362 + case 0x1500:
  1363 + switch (PPC_EXCP(env)) {
  1364 + case PPC_FLAGS_EXCP_602:
  1365 + /* Watchdog on 602 */
  1366 + cpu_abort(env,
  1367 + "602 watchdog exception is not implemented yet !\n");
  1368 + goto store_next;
  1369 + case PPC_FLAGS_EXCP_970:
  1370 + /* Soft patch exception on 970 */
  1371 + /* XXX: TODO */
  1372 + cpu_abort(env,
  1373 + "970 soft-patch exception is not implemented yet !\n");
  1374 + goto store_next;
  1375 + case PPC_FLAGS_EXCP_74xx:
  1376 + /* VPU assist on 74xx */
  1377 + /* XXX: TODO */
  1378 + cpu_abort(env, "VPU assist exception is not implemented yet !\n");
  1379 + goto store_next;
  1380 + default:
  1381 + cpu_abort(env, "Invalid exception 0x1500 !\n");
  1382 + break;
  1383 + }
  1384 + return;
  1385 + case 0x1600:
  1386 + switch (PPC_EXCP(env)) {
  1387 + case PPC_FLAGS_EXCP_602:
  1388 + /* Emulation trap on 602 */
  1389 + /* XXX: TODO */
  1390 + cpu_abort(env, "602 emulation trap exception "
  1391 + "is not implemented yet !\n");
  1392 + goto store_next;
  1393 + case PPC_FLAGS_EXCP_970:
  1394 + /* Maintenance exception on 970 */
  1395 + /* XXX: TODO */
  1396 + cpu_abort(env,
  1397 + "970 maintenance exception is not implemented yet !\n");
  1398 + goto store_next;
  1399 + default:
  1400 + cpu_abort(env, "Invalid exception 0x1600 !\n");
  1401 + break;
  1402 + }
  1403 + return;
  1404 + case 0x1700:
  1405 + switch (PPC_EXCP(env)) {
  1406 + case PPC_FLAGS_EXCP_7x0:
  1407 + case PPC_FLAGS_EXCP_7x5:
  1408 + /* Thermal management interrupt on G3 */
  1409 + /* XXX: TODO */
  1410 + cpu_abort(env, "G3 thermal management exception "
  1411 + "is not implemented yet !\n");
  1412 + goto store_next;
  1413 + case PPC_FLAGS_EXCP_970:
  1414 + /* VPU assist on 970 */
  1415 + /* XXX: TODO */
  1416 + cpu_abort(env,
  1417 + "970 VPU assist exception is not implemented yet !\n");
  1418 + goto store_next;
  1419 + default:
  1420 + cpu_abort(env, "Invalid exception 0x1700 !\n");
  1421 + break;
  1422 + }
  1423 + return;
  1424 + case 0x1800:
  1425 + switch (PPC_EXCP(env)) {
  1426 + case PPC_FLAGS_EXCP_970:
  1427 + /* Thermal exception on 970 */
  1428 + /* XXX: TODO */
  1429 + cpu_abort(env, "970 thermal management exception "
  1430 + "is not implemented yet !\n");
  1431 + goto store_next;
  1432 + default:
  1433 + cpu_abort(env, "Invalid exception 0x1800 !\n");
  1434 + break;
  1435 + }
  1436 + return;
  1437 + case 0x2000:
  1438 + switch (PPC_EXCP(env)) {
  1439 + case PPC_FLAGS_EXCP_40x:
  1440 + /* DEBUG on 4xx */
  1441 + /* XXX: TODO */
  1442 + cpu_abort(env, "40x debug exception is not implemented yet !\n");
  1443 + goto store_next;
  1444 + case PPC_FLAGS_EXCP_601:
  1445 + /* Run mode exception on 601 */
  1446 + /* XXX: TODO */
  1447 + cpu_abort(env,
  1448 + "601 run mode exception is not implemented yet !\n");
  1449 + goto store_next;
  1450 + default:
  1451 + cpu_abort(env, "Invalid exception 0x1800 !\n");
  1452 + break;
  1453 + }
  1454 + return;
  1455 + /* Other exceptions */
  1456 + /* Qemu internal exceptions:
  1457 + * we should never come here with those values: abort execution
  1458 + */
  1459 + default:
  1460 + cpu_abort(env, "Invalid exception: code %d (%04x)\n", excp, excp);
1172 return; 1461 return;
1173 store_current: 1462 store_current:
1174 - /* SRR0 is set to current instruction */  
1175 - env->spr[SPR_SRR0] = (uint32_t)env->nip - 4; 1463 + /* save current instruction location */
  1464 + *srr_0 = (env->nip - 4) & 0xFFFFFFFFULL;
1176 break; 1465 break;
1177 store_next: 1466 store_next:
1178 - /* SRR0 is set to next instruction */  
1179 - env->spr[SPR_SRR0] = (uint32_t)env->nip; 1467 + /* save next instruction location */
  1468 + *srr_0 = env->nip & 0xFFFFFFFFULL;
1180 break; 1469 break;
1181 } 1470 }
1182 - env->spr[SPR_SRR1] = msr; 1471 + /* Save msr */
  1472 + *srr_1 = msr;
  1473 + /* If we disactivated any translation, flush TLBs */
  1474 + if (msr_ir || msr_dr) {
  1475 + tlb_flush(env, 1);
  1476 + }
1183 /* reload MSR with correct bits */ 1477 /* reload MSR with correct bits */
1184 - msr_pow = 0;  
1185 msr_ee = 0; 1478 msr_ee = 0;
1186 msr_pr = 0; 1479 msr_pr = 0;
1187 msr_fp = 0; 1480 msr_fp = 0;
@@ -1193,14 +1486,11 @@ void do_interrupt (CPUState *env) @@ -1193,14 +1486,11 @@ void do_interrupt (CPUState *env)
1193 msr_dr = 0; 1486 msr_dr = 0;
1194 msr_ri = 0; 1487 msr_ri = 0;
1195 msr_le = msr_ile; 1488 msr_le = msr_ile;
  1489 + msr_sf = msr_isf;
1196 do_compute_hflags(env); 1490 do_compute_hflags(env);
1197 /* Jump to handler */ 1491 /* Jump to handler */
1198 - env->nip = excp << 8; 1492 + env->nip = excp;
1199 env->exception_index = EXCP_NONE; 1493 env->exception_index = EXCP_NONE;
1200 - /* Invalidate all TLB as we may have changed translation mode */  
1201 -#ifdef ACCURATE_TLB_FLUSH  
1202 - tlb_flush(env, 1);  
1203 -#endif  
1204 /* ensure that no TB jump will be modified as 1494 /* ensure that no TB jump will be modified as
1205 the program flow was changed */ 1495 the program flow was changed */
1206 #ifdef __sparc__ 1496 #ifdef __sparc__
@@ -1208,6 +1498,6 @@ void do_interrupt (CPUState *env) @@ -1208,6 +1498,6 @@ void do_interrupt (CPUState *env)
1208 #else 1498 #else
1209 T0 = 0; 1499 T0 = 0;
1210 #endif 1500 #endif
1211 - env->exception_index = -1; 1501 + env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1212 } 1502 }
1213 #endif /* !CONFIG_USER_ONLY */ 1503 #endif /* !CONFIG_USER_ONLY */
target-ppc/op.c
@@ -204,16 +204,6 @@ PPC_OP(update_nip) @@ -204,16 +204,6 @@ PPC_OP(update_nip)
204 env->nip = PARAM(1); 204 env->nip = PARAM(1);
205 } 205 }
206 206
207 -PPC_OP(debug)  
208 -{  
209 - env->nip = PARAM(1);  
210 -#if defined (DEBUG_OP)  
211 - dump_state();  
212 -#endif  
213 - do_raise_exception(EXCP_DEBUG);  
214 - RETURN();  
215 -}  
216 -  
217 /* Segment registers load and store with immediate index */ 207 /* Segment registers load and store with immediate index */
218 PPC_OP(load_srin) 208 PPC_OP(load_srin)
219 { 209 {
@@ -1384,14 +1374,10 @@ PPC_OP(check_reservation) @@ -1384,14 +1374,10 @@ PPC_OP(check_reservation)
1384 /* Return from interrupt */ 1374 /* Return from interrupt */
1385 PPC_OP(rfi) 1375 PPC_OP(rfi)
1386 { 1376 {
1387 - regs->nip = regs->spr[SPR_SRR0] & ~0x00000003;  
1388 -#if 1 // TRY  
1389 - T0 = regs->spr[SPR_SRR1] & ~0xFFF00000;  
1390 -#else  
1391 - T0 = regs->spr[SPR_SRR1] & ~0xFFFF0000;  
1392 -#endif 1377 + env->nip = env->spr[SPR_SRR0] & ~0x00000003;
  1378 + T0 = env->spr[SPR_SRR1] & ~0xFFFF0000UL;
1393 do_store_msr(env, T0); 1379 do_store_msr(env, T0);
1394 - do_raise_exception(EXCP_RFI); 1380 + env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1395 RETURN(); 1381 RETURN();
1396 } 1382 }
1397 1383
target-ppc/op_helper.c
@@ -42,12 +42,6 @@ void do_raise_exception_err (uint32_t exception, int error_code) @@ -42,12 +42,6 @@ void do_raise_exception_err (uint32_t exception, int error_code)
42 printf("Raise exception %3x code : %d\n", exception, error_code); 42 printf("Raise exception %3x code : %d\n", exception, error_code);
43 #endif 43 #endif
44 switch (exception) { 44 switch (exception) {
45 - case EXCP_EXTERNAL:  
46 - case EXCP_DECR:  
47 - printf("DECREMENTER & EXTERNAL exceptions should be hard interrupts !\n");  
48 - if (msr_ee == 0)  
49 - return;  
50 - break;  
51 case EXCP_PROGRAM: 45 case EXCP_PROGRAM:
52 if (error_code == EXCP_FP && msr_fe0 == 0 && msr_fe1 == 0) 46 if (error_code == EXCP_FP && msr_fe0 == 0 && msr_fe1 == 0)
53 return; 47 return;
target-ppc/translate.c
@@ -179,6 +179,12 @@ static inline void RET_STOP (DisasContext *ctx) @@ -179,6 +179,12 @@ static inline void RET_STOP (DisasContext *ctx)
179 RET_EXCP(ctx, EXCP_MTMSR, 0); 179 RET_EXCP(ctx, EXCP_MTMSR, 0);
180 } 180 }
181 181
  182 +static inline void RET_CHG_FLOW (DisasContext *ctx)
  183 +{
  184 + gen_op_raise_exception_err(EXCP_MTMSR, 0);
  185 + ctx->exception = EXCP_MTMSR;
  186 +}
  187 +
182 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \ 188 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
183 static void gen_##name (DisasContext *ctx); \ 189 static void gen_##name (DisasContext *ctx); \
184 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \ 190 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
@@ -1895,7 +1901,7 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW) @@ -1895,7 +1901,7 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1895 return; 1901 return;
1896 } 1902 }
1897 gen_op_rfi(); 1903 gen_op_rfi();
1898 - RET_EXCP(ctx, EXCP_RFI, 0); 1904 + RET_CHG_FLOW(ctx);
1899 #endif 1905 #endif
1900 } 1906 }
1901 1907
@@ -2555,7 +2561,8 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -2555,7 +2561,8 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2555 (msr_se && (ctx.nip < 0x100 || 2561 (msr_se && (ctx.nip < 0x100 ||
2556 ctx.nip > 0xF00 || 2562 ctx.nip > 0xF00 ||
2557 (ctx.nip & 0xFC) != 0x04) && 2563 (ctx.nip & 0xFC) != 0x04) &&
2558 - ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI && 2564 + ctx.exception != EXCP_SYSCALL &&
  2565 + ctx.exception != EXCP_SYSCALL_USER &&
2559 ctx.exception != EXCP_TRAP)) { 2566 ctx.exception != EXCP_TRAP)) {
2560 RET_EXCP(ctxp, EXCP_TRACE, 0); 2567 RET_EXCP(ctxp, EXCP_TRACE, 0);
2561 } 2568 }