Fix TB chaining for exceptions.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3721 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									185f07621f
								
							
						
					
					
						commit
						497ad68cd4
					
				
							
								
								
									
										52
									
								
								cpu-exec.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								cpu-exec.c
									
									
									
									
									
								
							@ -232,6 +232,11 @@ static inline TranslationBlock *tb_find_fast(void)
 | 
				
			|||||||
    return tb;
 | 
					    return tb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
				
			||||||
 | 
					#define BREAK_CHAIN tmp_T0 = 0
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define BREAK_CHAIN T0 = 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* main execution loop */
 | 
					/* main execution loop */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -405,11 +410,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                        svm_check_intercept(SVM_EXIT_SMI);
 | 
					                        svm_check_intercept(SVM_EXIT_SMI);
 | 
				
			||||||
                        env->interrupt_request &= ~CPU_INTERRUPT_SMI;
 | 
					                        env->interrupt_request &= ~CPU_INTERRUPT_SMI;
 | 
				
			||||||
                        do_smm_enter();
 | 
					                        do_smm_enter();
 | 
				
			||||||
#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                        tmp_T0 = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                        T0 = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
                    } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
					                    } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
				
			||||||
                        (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
 | 
					                        (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
 | 
				
			||||||
                        !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
 | 
					                        !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
 | 
				
			||||||
@ -423,11 +424,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                        do_interrupt(intno, 0, 0, 0, 1);
 | 
					                        do_interrupt(intno, 0, 0, 0, 1);
 | 
				
			||||||
                        /* ensure that no TB jump will be modified as
 | 
					                        /* ensure that no TB jump will be modified as
 | 
				
			||||||
                           the program flow was changed */
 | 
					                           the program flow was changed */
 | 
				
			||||||
#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                        tmp_T0 = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                        T0 = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
                    } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
 | 
					                    } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
 | 
				
			||||||
                        (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
 | 
					                        (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
 | 
				
			||||||
@ -441,11 +438,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
	                 do_interrupt(intno, 0, 0, -1, 1);
 | 
						                 do_interrupt(intno, 0, 0, -1, 1);
 | 
				
			||||||
                         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
 | 
					                         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
 | 
				
			||||||
                                  ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
 | 
					                                  ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
 | 
				
			||||||
#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                         tmp_T0 = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                         T0 = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
#elif defined(TARGET_PPC)
 | 
					#elif defined(TARGET_PPC)
 | 
				
			||||||
@ -458,11 +451,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                        ppc_hw_interrupt(env);
 | 
					                        ppc_hw_interrupt(env);
 | 
				
			||||||
                        if (env->pending_interrupts == 0)
 | 
					                        if (env->pending_interrupts == 0)
 | 
				
			||||||
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
					                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
				
			||||||
#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                        tmp_T0 = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                        T0 = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
#elif defined(TARGET_MIPS)
 | 
					#elif defined(TARGET_MIPS)
 | 
				
			||||||
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
					                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
				
			||||||
@ -475,11 +464,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                        env->exception_index = EXCP_EXT_INTERRUPT;
 | 
					                        env->exception_index = EXCP_EXT_INTERRUPT;
 | 
				
			||||||
                        env->error_code = 0;
 | 
					                        env->error_code = 0;
 | 
				
			||||||
                        do_interrupt(env);
 | 
					                        do_interrupt(env);
 | 
				
			||||||
#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                        tmp_T0 = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                        T0 = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
#elif defined(TARGET_SPARC)
 | 
					#elif defined(TARGET_SPARC)
 | 
				
			||||||
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
					                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
				
			||||||
@ -496,11 +481,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
 | 
					#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
                            cpu_check_irqs(env);
 | 
					                            cpu_check_irqs(env);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                            tmp_T0 = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                            T0 = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
 | 
							    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
 | 
				
			||||||
			//do_interrupt(0, 0, 0, 0, 0);
 | 
								//do_interrupt(0, 0, 0, 0, 0);
 | 
				
			||||||
@ -511,6 +492,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                        && !(env->uncached_cpsr & CPSR_F)) {
 | 
					                        && !(env->uncached_cpsr & CPSR_F)) {
 | 
				
			||||||
                        env->exception_index = EXCP_FIQ;
 | 
					                        env->exception_index = EXCP_FIQ;
 | 
				
			||||||
                        do_interrupt(env);
 | 
					                        do_interrupt(env);
 | 
				
			||||||
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    /* ARMv7-M interrupt return works by loading a magic value
 | 
					                    /* ARMv7-M interrupt return works by loading a magic value
 | 
				
			||||||
                       into the PC.  On real hardware the load causes the
 | 
					                       into the PC.  On real hardware the load causes the
 | 
				
			||||||
@ -526,17 +508,20 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                            || !(env->uncached_cpsr & CPSR_I))) {
 | 
					                            || !(env->uncached_cpsr & CPSR_I))) {
 | 
				
			||||||
                        env->exception_index = EXCP_IRQ;
 | 
					                        env->exception_index = EXCP_IRQ;
 | 
				
			||||||
                        do_interrupt(env);
 | 
					                        do_interrupt(env);
 | 
				
			||||||
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
#elif defined(TARGET_SH4)
 | 
					#elif defined(TARGET_SH4)
 | 
				
			||||||
		    /* XXXXX */
 | 
							    /* XXXXX */
 | 
				
			||||||
#elif defined(TARGET_ALPHA)
 | 
					#elif defined(TARGET_ALPHA)
 | 
				
			||||||
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
 | 
					                    if (interrupt_request & CPU_INTERRUPT_HARD) {
 | 
				
			||||||
                        do_interrupt(env);
 | 
					                        do_interrupt(env);
 | 
				
			||||||
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
#elif defined(TARGET_CRIS)
 | 
					#elif defined(TARGET_CRIS)
 | 
				
			||||||
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
 | 
					                    if (interrupt_request & CPU_INTERRUPT_HARD) {
 | 
				
			||||||
                        do_interrupt(env);
 | 
					                        do_interrupt(env);
 | 
				
			||||||
			env->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
								env->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
				
			||||||
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
#elif defined(TARGET_M68K)
 | 
					#elif defined(TARGET_M68K)
 | 
				
			||||||
                    if (interrupt_request & CPU_INTERRUPT_HARD
 | 
					                    if (interrupt_request & CPU_INTERRUPT_HARD
 | 
				
			||||||
@ -549,6 +534,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                           first signalled.  */
 | 
					                           first signalled.  */
 | 
				
			||||||
                        env->exception_index = env->pending_vector;
 | 
					                        env->exception_index = env->pending_vector;
 | 
				
			||||||
                        do_interrupt(1);
 | 
					                        do_interrupt(1);
 | 
				
			||||||
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                   /* Don't use the cached interupt_request value,
 | 
					                   /* Don't use the cached interupt_request value,
 | 
				
			||||||
@ -557,11 +543,7 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
 | 
					                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
 | 
				
			||||||
                        /* ensure that no TB jump will be modified as
 | 
					                        /* ensure that no TB jump will be modified as
 | 
				
			||||||
                           the program flow was changed */
 | 
					                           the program flow was changed */
 | 
				
			||||||
#if defined(__sparc__) && !defined(HOST_SOLARIS)
 | 
					                        BREAK_CHAIN;
 | 
				
			||||||
                        tmp_T0 = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                        T0 = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (interrupt_request & CPU_INTERRUPT_EXIT) {
 | 
					                    if (interrupt_request & CPU_INTERRUPT_EXIT) {
 | 
				
			||||||
                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
 | 
					                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user