Merge remote-tracking branch 'afaerber/qom-cpu' into staging
# By Andreas Färber (16) and Igor Mammedov (1) # Via Andreas Färber * afaerber/qom-cpu: target-lm32: Update VMStateDescription to LM32CPU target-arm: Override do_interrupt for ARMv7-M profile cpu: Replace do_interrupt() by CPUClass::do_interrupt method cpu: Pass CPUState to cpu_interrupt() exec: Pass CPUState to cpu_reset_interrupt() cpu: Move halted and interrupt_request fields to CPUState target-cris/helper.c: Update Coding Style target-i386: Update VMStateDescription to X86CPU cpu: Introduce cpu_class_set_vmsd() cpu: Register VMStateDescription through CPUState stubs: Add a vmstate_dummy struct for CONFIG_USER_ONLY vmstate: Make vmstate_register() static inline target-sh4: Move PVR/PRR/CVR into SuperHCPUClass target-sh4: Introduce SuperHCPU subclasses cpus: Replace open-coded CPU loop in qmp_memsave() with qemu_get_cpu() monitor: Use qemu_get_cpu() in monitor_set_cpu() cpu: Fix qemu_get_cpu() to return NULL if CPU not found
This commit is contained in:
		
						commit
						3d34a4110c
					
				
							
								
								
									
										70
									
								
								cpu-exec.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								cpu-exec.c
									
									
									
									
									
								
							@ -198,17 +198,21 @@ volatile sig_atomic_t exit_request;
 | 
			
		||||
int cpu_exec(CPUArchState *env)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cpu = ENV_GET_CPU(env);
 | 
			
		||||
#if !(defined(CONFIG_USER_ONLY) && \
 | 
			
		||||
      (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
 | 
			
		||||
    CPUClass *cc = CPU_GET_CLASS(cpu);
 | 
			
		||||
#endif
 | 
			
		||||
    int ret, interrupt_request;
 | 
			
		||||
    TranslationBlock *tb;
 | 
			
		||||
    uint8_t *tc_ptr;
 | 
			
		||||
    tcg_target_ulong next_tb;
 | 
			
		||||
 | 
			
		||||
    if (env->halted) {
 | 
			
		||||
    if (cpu->halted) {
 | 
			
		||||
        if (!cpu_has_work(cpu)) {
 | 
			
		||||
            return EXCP_HALTED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        env->halted = 0;
 | 
			
		||||
        cpu->halted = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cpu_single_env = env;
 | 
			
		||||
@ -265,12 +269,12 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                       which will be handled outside the cpu execution
 | 
			
		||||
                       loop */
 | 
			
		||||
#if defined(TARGET_I386)
 | 
			
		||||
                    do_interrupt(env);
 | 
			
		||||
                    cc->do_interrupt(cpu);
 | 
			
		||||
#endif
 | 
			
		||||
                    ret = env->exception_index;
 | 
			
		||||
                    break;
 | 
			
		||||
#else
 | 
			
		||||
                    do_interrupt(env);
 | 
			
		||||
                    cc->do_interrupt(cpu);
 | 
			
		||||
                    env->exception_index = -1;
 | 
			
		||||
#endif
 | 
			
		||||
                }
 | 
			
		||||
@ -278,14 +282,14 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
 | 
			
		||||
            next_tb = 0; /* force lookup of first TB */
 | 
			
		||||
            for(;;) {
 | 
			
		||||
                interrupt_request = env->interrupt_request;
 | 
			
		||||
                interrupt_request = cpu->interrupt_request;
 | 
			
		||||
                if (unlikely(interrupt_request)) {
 | 
			
		||||
                    if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
 | 
			
		||||
                        /* Mask out external interrupts for this step. */
 | 
			
		||||
                        interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_DEBUG) {
 | 
			
		||||
                        env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
 | 
			
		||||
                        cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
 | 
			
		||||
                        env->exception_index = EXCP_DEBUG;
 | 
			
		||||
                        cpu_loop_exit(env);
 | 
			
		||||
                    }
 | 
			
		||||
@ -293,8 +297,8 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
    defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
 | 
			
		||||
    defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_HALT) {
 | 
			
		||||
                        env->interrupt_request &= ~CPU_INTERRUPT_HALT;
 | 
			
		||||
                        env->halted = 1;
 | 
			
		||||
                        cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
 | 
			
		||||
                        cpu->halted = 1;
 | 
			
		||||
                        env->exception_index = EXCP_HLT;
 | 
			
		||||
                        cpu_loop_exit(env);
 | 
			
		||||
                    }
 | 
			
		||||
@ -302,7 +306,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
#if defined(TARGET_I386)
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_POLL) {
 | 
			
		||||
                        env->interrupt_request &= ~CPU_INTERRUPT_POLL;
 | 
			
		||||
                        cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
 | 
			
		||||
                        apic_poll_irq(env->apic_state);
 | 
			
		||||
                    }
 | 
			
		||||
#endif
 | 
			
		||||
@ -319,17 +323,17 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                            !(env->hflags & HF_SMM_MASK)) {
 | 
			
		||||
                            cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
 | 
			
		||||
                                                          0);
 | 
			
		||||
                            env->interrupt_request &= ~CPU_INTERRUPT_SMI;
 | 
			
		||||
                            cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
 | 
			
		||||
                            do_smm_enter(env);
 | 
			
		||||
                            next_tb = 0;
 | 
			
		||||
                        } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
 | 
			
		||||
                                   !(env->hflags2 & HF2_NMI_MASK)) {
 | 
			
		||||
                            env->interrupt_request &= ~CPU_INTERRUPT_NMI;
 | 
			
		||||
                            cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
 | 
			
		||||
                            env->hflags2 |= HF2_NMI_MASK;
 | 
			
		||||
                            do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
 | 
			
		||||
                            next_tb = 0;
 | 
			
		||||
                        } else if (interrupt_request & CPU_INTERRUPT_MCE) {
 | 
			
		||||
                            env->interrupt_request &= ~CPU_INTERRUPT_MCE;
 | 
			
		||||
                            cpu->interrupt_request &= ~CPU_INTERRUPT_MCE;
 | 
			
		||||
                            do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
 | 
			
		||||
                            next_tb = 0;
 | 
			
		||||
                        } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
@ -341,7 +345,8 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                            int intno;
 | 
			
		||||
                            cpu_svm_check_intercept_param(env, SVM_EXIT_INTR,
 | 
			
		||||
                                                          0);
 | 
			
		||||
                            env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
 | 
			
		||||
                            cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD |
 | 
			
		||||
                                                        CPU_INTERRUPT_VIRQ);
 | 
			
		||||
                            intno = cpu_get_pic_interrupt(env);
 | 
			
		||||
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
 | 
			
		||||
                            do_interrupt_x86_hardirq(env, intno, 1);
 | 
			
		||||
@ -359,7 +364,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                            intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
 | 
			
		||||
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
 | 
			
		||||
                            do_interrupt_x86_hardirq(env, intno, 1);
 | 
			
		||||
                            env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
 | 
			
		||||
                            cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
 | 
			
		||||
                            next_tb = 0;
 | 
			
		||||
#endif
 | 
			
		||||
                        }
 | 
			
		||||
@ -370,15 +375,16 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                    }
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
 | 
			
		||||
                        ppc_hw_interrupt(env);
 | 
			
		||||
                        if (env->pending_interrupts == 0)
 | 
			
		||||
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
			
		||||
                        if (env->pending_interrupts == 0) {
 | 
			
		||||
                            cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
			
		||||
                        }
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_LM32)
 | 
			
		||||
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
 | 
			
		||||
                        && (env->ie & IE_IE)) {
 | 
			
		||||
                        env->exception_index = EXCP_IRQ;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_MICROBLAZE)
 | 
			
		||||
@ -387,7 +393,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                        && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
 | 
			
		||||
                        && !(env->iflags & (D_FLAG | IMM_FLAG))) {
 | 
			
		||||
                        env->exception_index = EXCP_IRQ;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_MIPS)
 | 
			
		||||
@ -396,7 +402,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                        /* Raise it */
 | 
			
		||||
                        env->exception_index = EXCP_EXT_INTERRUPT;
 | 
			
		||||
                        env->error_code = 0;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_OPENRISC)
 | 
			
		||||
@ -412,7 +418,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                        }
 | 
			
		||||
                        if (idx >= 0) {
 | 
			
		||||
                            env->exception_index = idx;
 | 
			
		||||
                            do_interrupt(env);
 | 
			
		||||
                            cc->do_interrupt(cpu);
 | 
			
		||||
                            next_tb = 0;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@ -427,7 +433,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                                  cpu_pil_allowed(env, pil)) ||
 | 
			
		||||
                                  type != TT_EXTINT) {
 | 
			
		||||
                                env->exception_index = env->interrupt_index;
 | 
			
		||||
                                do_interrupt(env);
 | 
			
		||||
                                cc->do_interrupt(cpu);
 | 
			
		||||
                                next_tb = 0;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
@ -436,7 +442,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_FIQ
 | 
			
		||||
                        && !(env->uncached_cpsr & CPSR_F)) {
 | 
			
		||||
                        env->exception_index = EXCP_FIQ;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    /* ARMv7-M interrupt return works by loading a magic value
 | 
			
		||||
@ -452,19 +458,19 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
 | 
			
		||||
                            || !(env->uncached_cpsr & CPSR_I))) {
 | 
			
		||||
                        env->exception_index = EXCP_IRQ;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_UNICORE32)
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_HARD
 | 
			
		||||
                        && !(env->uncached_asr & ASR_I)) {
 | 
			
		||||
                        env->exception_index = UC32_EXCP_INTR;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_SH4)
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_ALPHA)
 | 
			
		||||
@ -495,7 +501,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                        if (idx >= 0) {
 | 
			
		||||
                            env->exception_index = idx;
 | 
			
		||||
                            env->error_code = 0;
 | 
			
		||||
                            do_interrupt(env);
 | 
			
		||||
                            cc->do_interrupt(cpu);
 | 
			
		||||
                            next_tb = 0;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@ -504,7 +510,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                        && (env->pregs[PR_CCS] & I_FLAG)
 | 
			
		||||
                        && !env->locked_irq) {
 | 
			
		||||
                        env->exception_index = EXCP_IRQ;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_NMI) {
 | 
			
		||||
@ -516,7 +522,7 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
                        }
 | 
			
		||||
                        if ((env->pregs[PR_CCS] & m_flag_archval)) {
 | 
			
		||||
                            env->exception_index = EXCP_NMI;
 | 
			
		||||
                            do_interrupt(env);
 | 
			
		||||
                            cc->do_interrupt(cpu);
 | 
			
		||||
                            next_tb = 0;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@ -536,20 +542,20 @@ int cpu_exec(CPUArchState *env)
 | 
			
		||||
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
 | 
			
		||||
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
                        (env->psw.mask & PSW_MASK_EXT)) {
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#elif defined(TARGET_XTENSA)
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
 | 
			
		||||
                        env->exception_index = EXC_IRQ;
 | 
			
		||||
                        do_interrupt(env);
 | 
			
		||||
                        cc->do_interrupt(cpu);
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
#endif
 | 
			
		||||
                   /* Don't use the cached interrupt_request value,
 | 
			
		||||
                      do_interrupt may have updated the EXITTB flag. */
 | 
			
		||||
                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
 | 
			
		||||
                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
 | 
			
		||||
                    if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
 | 
			
		||||
                        cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
 | 
			
		||||
                        /* ensure that no TB jump will be modified as
 | 
			
		||||
                           the program flow was changed */
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								cpus.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								cpus.c
									
									
									
									
									
								
							@ -72,7 +72,7 @@ static bool cpu_thread_is_idle(CPUArchState *env)
 | 
			
		||||
    if (cpu->stopped || !runstate_is_running()) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (!env->halted || qemu_cpu_has_work(cpu) ||
 | 
			
		||||
    if (!cpu->halted || qemu_cpu_has_work(cpu) ||
 | 
			
		||||
        kvm_async_interrupts_enabled()) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
@ -1198,7 +1198,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 | 
			
		||||
        info->value = g_malloc0(sizeof(*info->value));
 | 
			
		||||
        info->value->CPU = cpu->cpu_index;
 | 
			
		||||
        info->value->current = (env == first_cpu);
 | 
			
		||||
        info->value->halted = env->halted;
 | 
			
		||||
        info->value->halted = cpu->halted;
 | 
			
		||||
        info->value->thread_id = cpu->thread_id;
 | 
			
		||||
#if defined(TARGET_I386)
 | 
			
		||||
        info->value->has_pc = true;
 | 
			
		||||
@ -1241,18 +1241,13 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
 | 
			
		||||
        cpu_index = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (env = first_cpu; env; env = env->next_cpu) {
 | 
			
		||||
        cpu = ENV_GET_CPU(env);
 | 
			
		||||
        if (cpu_index == cpu->cpu_index) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (env == NULL) {
 | 
			
		||||
    cpu = qemu_get_cpu(cpu_index);
 | 
			
		||||
    if (cpu == NULL) {
 | 
			
		||||
        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
 | 
			
		||||
                  "a CPU number");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    env = cpu->env_ptr;
 | 
			
		||||
 | 
			
		||||
    f = fopen(filename, "wb");
 | 
			
		||||
    if (!f) {
 | 
			
		||||
@ -1314,7 +1309,7 @@ void qmp_inject_nmi(Error **errp)
 | 
			
		||||
 | 
			
		||||
    for (env = first_cpu; env != NULL; env = env->next_cpu) {
 | 
			
		||||
        if (!env->apic_state) {
 | 
			
		||||
            cpu_interrupt(env, CPU_INTERRUPT_NMI);
 | 
			
		||||
            cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_NMI);
 | 
			
		||||
        } else {
 | 
			
		||||
            apic_deliver_nmi(env->apic_state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								exec.c
									
									
									
									
									
								
							@ -219,16 +219,16 @@ void cpu_exec_init_all(void)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
static int cpu_common_post_load(void *opaque, int version_id)
 | 
			
		||||
{
 | 
			
		||||
    CPUArchState *env = opaque;
 | 
			
		||||
    CPUState *cpu = opaque;
 | 
			
		||||
 | 
			
		||||
    /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
 | 
			
		||||
       version_id is increased. */
 | 
			
		||||
    env->interrupt_request &= ~0x01;
 | 
			
		||||
    tlb_flush(env, 1);
 | 
			
		||||
    cpu->interrupt_request &= ~0x01;
 | 
			
		||||
    tlb_flush(cpu->env_ptr, 1);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -240,11 +240,13 @@ static const VMStateDescription vmstate_cpu_common = {
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .post_load = cpu_common_post_load,
 | 
			
		||||
    .fields      = (VMStateField []) {
 | 
			
		||||
        VMSTATE_UINT32(halted, CPUArchState),
 | 
			
		||||
        VMSTATE_UINT32(interrupt_request, CPUArchState),
 | 
			
		||||
        VMSTATE_UINT32(halted, CPUState),
 | 
			
		||||
        VMSTATE_UINT32(interrupt_request, CPUState),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
#else
 | 
			
		||||
#define vmstate_cpu_common vmstate_dummy
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
CPUState *qemu_get_cpu(int index)
 | 
			
		||||
@ -260,12 +262,13 @@ CPUState *qemu_get_cpu(int index)
 | 
			
		||||
        env = env->next_cpu;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cpu;
 | 
			
		||||
    return env ? cpu : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cpu_exec_init(CPUArchState *env)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cpu = ENV_GET_CPU(env);
 | 
			
		||||
    CPUClass *cc = CPU_GET_CLASS(cpu);
 | 
			
		||||
    CPUArchState **penv;
 | 
			
		||||
    int cpu_index;
 | 
			
		||||
 | 
			
		||||
@ -290,11 +293,15 @@ void cpu_exec_init(CPUArchState *env)
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
    cpu_list_unlock();
 | 
			
		||||
#endif
 | 
			
		||||
    vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
 | 
			
		||||
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env);
 | 
			
		||||
    register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
 | 
			
		||||
                    cpu_save, cpu_load, env);
 | 
			
		||||
    assert(cc->vmsd == NULL);
 | 
			
		||||
#endif
 | 
			
		||||
    if (cc->vmsd != NULL) {
 | 
			
		||||
        vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(TARGET_HAS_ICE)
 | 
			
		||||
@ -485,11 +492,6 @@ void cpu_single_step(CPUArchState *env, int enabled)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cpu_reset_interrupt(CPUArchState *env, int mask)
 | 
			
		||||
{
 | 
			
		||||
    env->interrupt_request &= ~mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cpu_exit(CPUArchState *env)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cpu = ENV_GET_CPU(env);
 | 
			
		||||
@ -1476,7 +1478,7 @@ static void check_watchpoint(int offset, int len_mask, int flags)
 | 
			
		||||
        /* We re-entered the check after replacing the TB. Now raise
 | 
			
		||||
         * the debug interrupt so that is will trigger after the
 | 
			
		||||
         * current instruction. */
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_DEBUG);
 | 
			
		||||
        cpu_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_DEBUG);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
 | 
			
		||||
 | 
			
		||||
@ -2408,7 +2408,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
 | 
			
		||||
                cpu_synchronize_state(env);
 | 
			
		||||
                len = snprintf((char *)mem_buf, sizeof(mem_buf),
 | 
			
		||||
                               "CPU#%d [%s]", cpu->cpu_index,
 | 
			
		||||
                               env->halted ? "halted " : "running");
 | 
			
		||||
                               cpu->halted ? "halted " : "running");
 | 
			
		||||
                memtohex(buf, mem_buf, len);
 | 
			
		||||
                put_packet(s, buf);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -62,11 +62,11 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
 | 
			
		||||
{
 | 
			
		||||
    /* If there are any non-masked interrupts, tell the cpu.  */
 | 
			
		||||
    if (cpu != NULL) {
 | 
			
		||||
        CPUAlphaState *env = &cpu->env;
 | 
			
		||||
        CPUState *cs = CPU(cpu);
 | 
			
		||||
        if (req) {
 | 
			
		||||
            cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -358,17 +358,17 @@ static void cchip_write(void *opaque, hwaddr addr,
 | 
			
		||||
            for (i = 0; i < 4; ++i) {
 | 
			
		||||
                AlphaCPU *cpu = s->cchip.cpu[i];
 | 
			
		||||
                if (cpu != NULL) {
 | 
			
		||||
                    CPUAlphaState *env = &cpu->env;
 | 
			
		||||
                    CPUState *cs = CPU(cpu);
 | 
			
		||||
                    /* IPI can be either cleared or set by the write.  */
 | 
			
		||||
                    if (newval & (1 << (i + 8))) {
 | 
			
		||||
                        cpu_interrupt(env, CPU_INTERRUPT_SMP);
 | 
			
		||||
                        cpu_interrupt(cs, CPU_INTERRUPT_SMP);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        cpu_reset_interrupt(env, CPU_INTERRUPT_SMP);
 | 
			
		||||
                        cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /* ITI can only be cleared by the write.  */
 | 
			
		||||
                    if ((newval & (1 << (i + 4))) == 0) {
 | 
			
		||||
                        cpu_reset_interrupt(env, CPU_INTERRUPT_TIMER);
 | 
			
		||||
                        cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -685,7 +685,7 @@ static void typhoon_set_timer_irq(void *opaque, int irq, int level)
 | 
			
		||||
                /* Set the ITI bit for this cpu.  */
 | 
			
		||||
                s->cchip.misc |= 1 << (i + 4);
 | 
			
		||||
                /* And signal the interrupt.  */
 | 
			
		||||
                cpu_interrupt(&cpu->env, CPU_INTERRUPT_TIMER);
 | 
			
		||||
                cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TIMER);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -698,7 +698,7 @@ static void typhoon_alarm_timer(void *opaque)
 | 
			
		||||
 | 
			
		||||
    /* Set the ITI bit for this cpu.  */
 | 
			
		||||
    s->cchip.misc |= 1 << (cpu + 4);
 | 
			
		||||
    cpu_interrupt(&s->cchip.cpu[cpu]->env, CPU_INTERRUPT_TIMER);
 | 
			
		||||
    cpu_interrupt(CPU(s->cchip.cpu[cpu]), CPU_INTERRUPT_TIMER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								hw/apic.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								hw/apic.c
									
									
									
									
									
								
							@ -151,15 +151,15 @@ static void apic_local_deliver(APICCommonState *s, int vector)
 | 
			
		||||
 | 
			
		||||
    switch ((lvt >> 8) & 7) {
 | 
			
		||||
    case APIC_DM_SMI:
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_SMI);
 | 
			
		||||
        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SMI);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case APIC_DM_NMI:
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_NMI);
 | 
			
		||||
        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_NMI);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case APIC_DM_EXTINT:
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case APIC_DM_FIXED:
 | 
			
		||||
@ -187,7 +187,7 @@ void apic_deliver_pic_intr(DeviceState *d, int level)
 | 
			
		||||
            reset_bit(s->irr, lvt & 0xff);
 | 
			
		||||
            /* fall through */
 | 
			
		||||
        case APIC_DM_EXTINT:
 | 
			
		||||
            cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -248,20 +248,20 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask,
 | 
			
		||||
 | 
			
		||||
        case APIC_DM_SMI:
 | 
			
		||||
            foreach_apic(apic_iter, deliver_bitmask,
 | 
			
		||||
                cpu_interrupt(&apic_iter->cpu->env, CPU_INTERRUPT_SMI)
 | 
			
		||||
                cpu_interrupt(CPU(apic_iter->cpu), CPU_INTERRUPT_SMI)
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case APIC_DM_NMI:
 | 
			
		||||
            foreach_apic(apic_iter, deliver_bitmask,
 | 
			
		||||
                cpu_interrupt(&apic_iter->cpu->env, CPU_INTERRUPT_NMI)
 | 
			
		||||
                cpu_interrupt(CPU(apic_iter->cpu), CPU_INTERRUPT_NMI)
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case APIC_DM_INIT:
 | 
			
		||||
            /* normal INIT IPI sent to processors */
 | 
			
		||||
            foreach_apic(apic_iter, deliver_bitmask,
 | 
			
		||||
                         cpu_interrupt(&apic_iter->cpu->env,
 | 
			
		||||
                         cpu_interrupt(CPU(apic_iter->cpu),
 | 
			
		||||
                                       CPU_INTERRUPT_INIT)
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
@ -363,15 +363,16 @@ static int apic_irq_pending(APICCommonState *s)
 | 
			
		||||
/* signal the CPU if an irq is pending */
 | 
			
		||||
static void apic_update_irq(APICCommonState *s)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cpu = CPU(s->cpu);
 | 
			
		||||
    CPUState *cpu;
 | 
			
		||||
 | 
			
		||||
    if (!(s->spurious_vec & APIC_SV_ENABLE)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    cpu = CPU(s->cpu);
 | 
			
		||||
    if (!qemu_cpu_is_self(cpu)) {
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_POLL);
 | 
			
		||||
        cpu_interrupt(cpu, CPU_INTERRUPT_POLL);
 | 
			
		||||
    } else if (apic_irq_pending(s) > 0) {
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -478,14 +479,14 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
 | 
			
		||||
static void apic_startup(APICCommonState *s, int vector_num)
 | 
			
		||||
{
 | 
			
		||||
    s->sipi_vector = vector_num;
 | 
			
		||||
    cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_SIPI);
 | 
			
		||||
    cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void apic_sipi(DeviceState *d)
 | 
			
		||||
{
 | 
			
		||||
    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
 | 
			
		||||
 | 
			
		||||
    cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_SIPI);
 | 
			
		||||
    cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
 | 
			
		||||
 | 
			
		||||
    if (!s->wait_for_sipi)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
@ -1523,7 +1523,7 @@ static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
 | 
			
		||||
    omap_clk clk;
 | 
			
		||||
 | 
			
		||||
    if (value & (1 << 11)) {                            /* SETARM_IDLE */
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HALT);
 | 
			
		||||
        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
 | 
			
		||||
    }
 | 
			
		||||
    if (!(value & (1 << 10)))				/* WKUP_MODE */
 | 
			
		||||
        qemu_system_shutdown_request();	/* XXX: disable wakeup from IRQ */
 | 
			
		||||
@ -1721,6 +1721,7 @@ static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
 | 
			
		||||
                                 unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 | 
			
		||||
    CPUState *cpu = CPU(s->cpu);
 | 
			
		||||
 | 
			
		||||
    if (size != 2) {
 | 
			
		||||
        return omap_badwidth_read16(opaque, addr);
 | 
			
		||||
@ -1737,8 +1738,9 @@ static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
 | 
			
		||||
        return s->clkm.dsp_rstct2;
 | 
			
		||||
 | 
			
		||||
    case 0x18:	/* DSP_SYSST */
 | 
			
		||||
        cpu = CPU(s->cpu);
 | 
			
		||||
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
 | 
			
		||||
                (s->cpu->env.halted << 6);      /* Quite useless... */
 | 
			
		||||
                (cpu->halted << 6);      /* Quite useless... */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    OMAP_BAD_REG(addr);
 | 
			
		||||
@ -3754,9 +3756,10 @@ static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
 | 
			
		||||
void omap_mpu_wakeup(void *opaque, int irq, int req)
 | 
			
		||||
{
 | 
			
		||||
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
 | 
			
		||||
    CPUState *cpu = CPU(mpu->cpu);
 | 
			
		||||
 | 
			
		||||
    if (mpu->cpu->env.halted) {
 | 
			
		||||
        cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB);
 | 
			
		||||
    if (cpu->halted) {
 | 
			
		||||
        cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,20 +15,22 @@
 | 
			
		||||
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    ARMCPU *cpu = opaque;
 | 
			
		||||
    CPUARMState *env = &cpu->env;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    switch (irq) {
 | 
			
		||||
    case ARM_PIC_CPU_IRQ:
 | 
			
		||||
        if (level)
 | 
			
		||||
            cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        else
 | 
			
		||||
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        if (level) {
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case ARM_PIC_CPU_FIQ:
 | 
			
		||||
        if (level)
 | 
			
		||||
            cpu_interrupt(env, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        else
 | 
			
		||||
            cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        if (level) {
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
 | 
			
		||||
 | 
			
		||||
@ -263,14 +263,14 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
    case 1:
 | 
			
		||||
        /* Idle */
 | 
			
		||||
        if (!(s->cm_regs[CCCR >> 2] & (1 << 31))) { /* CPDIS */
 | 
			
		||||
            cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HALT);
 | 
			
		||||
            cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        /* Fall through.  */
 | 
			
		||||
 | 
			
		||||
    case 2:
 | 
			
		||||
        /* Deep-Idle */
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HALT);
 | 
			
		||||
        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
 | 
			
		||||
        s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
 | 
			
		||||
        goto message;
 | 
			
		||||
 | 
			
		||||
@ -301,7 +301,8 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        /* Suspend */
 | 
			
		||||
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
 | 
			
		||||
        cpu_interrupt(CPU(arm_env_get_cpu(cpu_single_env)),
 | 
			
		||||
                      CPU_INTERRUPT_HALT);
 | 
			
		||||
 | 
			
		||||
        goto message;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,7 @@ static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
 | 
			
		||||
static void pxa2xx_gpio_set(void *opaque, int line, int level)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;
 | 
			
		||||
    CPUState *cpu = CPU(s->cpu);
 | 
			
		||||
    int bank;
 | 
			
		||||
    uint32_t mask;
 | 
			
		||||
 | 
			
		||||
@ -118,8 +119,8 @@ static void pxa2xx_gpio_set(void *opaque, int line, int level)
 | 
			
		||||
        pxa2xx_gpio_irq_update(s);
 | 
			
		||||
 | 
			
		||||
    /* Wake-up GPIOs */
 | 
			
		||||
    if (s->cpu->env.halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) {
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_EXITTB);
 | 
			
		||||
    if (cpu->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) {
 | 
			
		||||
        cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,12 +46,13 @@ static void pxa2xx_pic_update(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t mask[2];
 | 
			
		||||
    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
 | 
			
		||||
    CPUState *cpu = CPU(s->cpu);
 | 
			
		||||
 | 
			
		||||
    if (s->cpu->env.halted) {
 | 
			
		||||
    if (cpu->halted) {
 | 
			
		||||
        mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
 | 
			
		||||
        mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
 | 
			
		||||
        if (mask[0] || mask[1]) {
 | 
			
		||||
            cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_EXITTB);
 | 
			
		||||
            cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -59,15 +60,15 @@ static void pxa2xx_pic_update(void *opaque)
 | 
			
		||||
    mask[1] = s->int_pending[1] & s->int_enabled[1];
 | 
			
		||||
 | 
			
		||||
    if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])) {
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        cpu_interrupt(cpu, CPU_INTERRUPT_FIQ);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        cpu_reset_interrupt(cpu, CPU_INTERRUPT_FIQ);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])) {
 | 
			
		||||
        cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -30,16 +30,18 @@
 | 
			
		||||
 | 
			
		||||
static void cris_pic_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPUCRISState *env = (CPUCRISState *)opaque;
 | 
			
		||||
    CRISCPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD;
 | 
			
		||||
 | 
			
		||||
    if (level)
 | 
			
		||||
        cpu_interrupt(env, type);
 | 
			
		||||
    else
 | 
			
		||||
        cpu_reset_interrupt(env, type);
 | 
			
		||||
    if (level) {
 | 
			
		||||
        cpu_interrupt(cs, type);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(cs, type);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qemu_irq *cris_pic_init_cpu(CPUCRISState *env)
 | 
			
		||||
{
 | 
			
		||||
    return qemu_allocate_irqs(cris_pic_cpu_handler, env, 2);
 | 
			
		||||
    return qemu_allocate_irqs(cris_pic_cpu_handler, cris_env_get_cpu(env), 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								hw/i386/pc.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								hw/i386/pc.c
									
									
									
									
									
								
							@ -190,10 +190,12 @@ static void pic_irq_request(void *opaque, int irq, int level)
 | 
			
		||||
            env = env->next_cpu;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if (level)
 | 
			
		||||
            cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        else
 | 
			
		||||
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        CPUState *cs = CPU(x86_env_get_cpu(env));
 | 
			
		||||
        if (level) {
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -854,10 +856,10 @@ DeviceState *cpu_get_current_apic(void)
 | 
			
		||||
 | 
			
		||||
void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *s = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
 | 
			
		||||
    if (level) {
 | 
			
		||||
        cpu_interrupt(s, CPU_INTERRUPT_SMI);
 | 
			
		||||
        cpu_interrupt(CPU(cpu), CPU_INTERRUPT_SMI);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -205,7 +205,8 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		||||
    if (pci_enabled && acpi_enabled) {
 | 
			
		||||
        i2c_bus *smbus;
 | 
			
		||||
 | 
			
		||||
        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
 | 
			
		||||
        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt,
 | 
			
		||||
                                     x86_env_get_cpu(first_cpu), 1);
 | 
			
		||||
        /* TODO: Populate SPD eeprom data.  */
 | 
			
		||||
        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
 | 
			
		||||
                              gsi[9], *smi_irq,
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ static void xen_init_pv(QEMUMachineInitArgs *args)
 | 
			
		||||
    const char *kernel_cmdline = args->kernel_cmdline;
 | 
			
		||||
    const char *initrd_filename = args->initrd_filename;
 | 
			
		||||
    X86CPU *cpu;
 | 
			
		||||
    CPUX86State *env;
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
    DriveInfo *dinfo;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
@ -49,8 +49,8 @@ static void xen_init_pv(QEMUMachineInitArgs *args)
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    cpu = cpu_x86_init(cpu_model);
 | 
			
		||||
    env = &cpu->env;
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    cs = CPU(cpu);
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
 | 
			
		||||
    /* Initialize backend core & drivers */
 | 
			
		||||
    if (xen_be_init() != 0) {
 | 
			
		||||
 | 
			
		||||
@ -41,12 +41,13 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
static void cpu_irq_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPULM32State *env = opaque;
 | 
			
		||||
    LM32CPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    if (level) {
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -117,7 +118,7 @@ static void lm32_evr_init(QEMUMachineInitArgs *args)
 | 
			
		||||
                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 | 
			
		||||
 | 
			
		||||
    /* create irq lines */
 | 
			
		||||
    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
 | 
			
		||||
    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);
 | 
			
		||||
    env->pic_state = lm32_pic_init(*cpu_irq);
 | 
			
		||||
    for (i = 0; i < 32; i++) {
 | 
			
		||||
        irq[i] = qdev_get_gpio_in(env->pic_state, i);
 | 
			
		||||
 | 
			
		||||
@ -46,12 +46,13 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
static void cpu_irq_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPULM32State *env = opaque;
 | 
			
		||||
    LM32CPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    if (level) {
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -123,7 +124,7 @@ milkymist_init(QEMUMachineInitArgs *args)
 | 
			
		||||
                          0x00, 0x89, 0x00, 0x1d, 1);
 | 
			
		||||
 | 
			
		||||
    /* create irq lines */
 | 
			
		||||
    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
 | 
			
		||||
    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);
 | 
			
		||||
    env->pic_state = lm32_pic_init(*cpu_irq);
 | 
			
		||||
    for (i = 0; i < 32; i++) {
 | 
			
		||||
        irq[i] = qdev_get_gpio_in(env->pic_state, i);
 | 
			
		||||
 | 
			
		||||
@ -381,7 +381,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
 | 
			
		||||
 | 
			
		||||
    /* SMI_EN = PMBASE + 30. SMI control and enable register */
 | 
			
		||||
    if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
 | 
			
		||||
        cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
 | 
			
		||||
        cpu_interrupt(CPU(x86_env_get_cpu(first_cpu)), CPU_INTERRUPT_SMI);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,16 +29,19 @@
 | 
			
		||||
 | 
			
		||||
static void microblaze_pic_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPUMBState *env = (CPUMBState *)opaque;
 | 
			
		||||
    MicroBlazeCPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD;
 | 
			
		||||
 | 
			
		||||
    if (level)
 | 
			
		||||
        cpu_interrupt(env, type);
 | 
			
		||||
    else
 | 
			
		||||
        cpu_reset_interrupt(env, type);
 | 
			
		||||
    if (level) {
 | 
			
		||||
        cpu_interrupt(cs, type);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(cs, type);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qemu_irq *microblaze_pic_init_cpu(CPUMBState *env)
 | 
			
		||||
{
 | 
			
		||||
    return qemu_allocate_irqs(microblaze_pic_cpu_handler, env, 2);
 | 
			
		||||
    return qemu_allocate_irqs(microblaze_pic_cpu_handler, mb_env_get_cpu(env),
 | 
			
		||||
                              2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,9 @@
 | 
			
		||||
 | 
			
		||||
static void cpu_mips_irq_request(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPUMIPSState *env = (CPUMIPSState *)opaque;
 | 
			
		||||
    MIPSCPU *cpu = opaque;
 | 
			
		||||
    CPUMIPSState *env = &cpu->env;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    if (irq < 0 || irq > 7)
 | 
			
		||||
        return;
 | 
			
		||||
@ -38,9 +40,9 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (env->CP0_Cause & CP0Ca_IP_mask) {
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -49,7 +51,7 @@ void cpu_mips_irq_init_cpu(CPUMIPSState *env)
 | 
			
		||||
    qemu_irq *qi;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    qi = qemu_allocate_irqs(cpu_mips_irq_request, env, 8);
 | 
			
		||||
    qi = qemu_allocate_irqs(cpu_mips_irq_request, mips_env_get_cpu(env), 8);
 | 
			
		||||
    for (i = 0; i < 8; i++) {
 | 
			
		||||
        env->irq[i] = qi[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -73,8 +73,10 @@ static void openrisc_timer_cb(void *opaque)
 | 
			
		||||
 | 
			
		||||
    if ((cpu->env.ttmr & TTMR_IE) &&
 | 
			
		||||
         qemu_timer_expired(cpu->env.timer, qemu_get_clock_ns(vm_clock))) {
 | 
			
		||||
        CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
        cpu->env.ttmr |= TTMR_IP;
 | 
			
		||||
        cpu->env.interrupt_request |= CPU_INTERRUPT_TIMER;
 | 
			
		||||
        cs->interrupt_request |= CPU_INTERRUPT_TIMER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (cpu->env.ttmr & TTMR_M) {
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@
 | 
			
		||||
static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    int i;
 | 
			
		||||
    uint32_t irq_bit = 1 << irq;
 | 
			
		||||
 | 
			
		||||
@ -40,9 +41,9 @@ static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < 32; i++) {
 | 
			
		||||
        if ((cpu->env.picsr && (1 << i)) && (cpu->env.picmr && (1 << i))) {
 | 
			
		||||
            cpu_interrupt(&cpu->env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_reset_interrupt(&cpu->env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu->env.picsr &= ~(1 << i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -420,26 +420,28 @@ static void mmubooke_create_initial_mapping(CPUPPCState *env)
 | 
			
		||||
static void ppce500_cpu_reset_sec(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    PowerPCCPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUPPCState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    cpu_reset(CPU(cpu));
 | 
			
		||||
    cpu_reset(cs);
 | 
			
		||||
 | 
			
		||||
    /* Secondary CPU starts in halted state for now. Needs to change when
 | 
			
		||||
       implementing non-kernel boot. */
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
    env->exception_index = EXCP_HLT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ppce500_cpu_reset(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    PowerPCCPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUPPCState *env = &cpu->env;
 | 
			
		||||
    struct boot_info *bi = env->load_info;
 | 
			
		||||
 | 
			
		||||
    cpu_reset(CPU(cpu));
 | 
			
		||||
    cpu_reset(cs);
 | 
			
		||||
 | 
			
		||||
    /* Set initial guest state. */
 | 
			
		||||
    env->halted = 0;
 | 
			
		||||
    cs->halted = 0;
 | 
			
		||||
    env->gpr[1] = (16<<20) - 8;
 | 
			
		||||
    env->gpr[3] = bi->dt_base;
 | 
			
		||||
    env->nip = bi->entry;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								hw/ppc/ppc.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								hw/ppc/ppc.c
									
									
									
									
									
								
							@ -52,16 +52,18 @@ static void cpu_ppc_tb_start (CPUPPCState *env);
 | 
			
		||||
 | 
			
		||||
void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUPPCState *env = &cpu->env;
 | 
			
		||||
    unsigned int old_pending = env->pending_interrupts;
 | 
			
		||||
 | 
			
		||||
    if (level) {
 | 
			
		||||
        env->pending_interrupts |= 1 << n_IRQ;
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    } else {
 | 
			
		||||
        env->pending_interrupts &= ~(1 << n_IRQ);
 | 
			
		||||
        if (env->pending_interrupts == 0)
 | 
			
		||||
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        if (env->pending_interrupts == 0) {
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (old_pending != env->pending_interrupts) {
 | 
			
		||||
@ -72,7 +74,7 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level)
 | 
			
		||||
 | 
			
		||||
    LOG_IRQ("%s: %p n_IRQ %d level %d => pending %08" PRIx32
 | 
			
		||||
                "req %08x\n", __func__, env, n_IRQ, level,
 | 
			
		||||
                env->pending_interrupts, env->interrupt_request);
 | 
			
		||||
                env->pending_interrupts, CPU(cpu)->interrupt_request);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* PowerPC 6xx / 7xx internal IRQ controller */
 | 
			
		||||
@ -87,6 +89,8 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level)
 | 
			
		||||
    cur_level = (env->irq_input_state >> pin) & 1;
 | 
			
		||||
    /* Don't generate spurious events */
 | 
			
		||||
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
 | 
			
		||||
        CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
        switch (pin) {
 | 
			
		||||
        case PPC6xx_INPUT_TBEN:
 | 
			
		||||
            /* Level sensitive - active high */
 | 
			
		||||
@ -126,14 +130,14 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level)
 | 
			
		||||
            /* XXX: Note that the only way to restart the CPU is to reset it */
 | 
			
		||||
            if (level) {
 | 
			
		||||
                LOG_IRQ("%s: stop the CPU\n", __func__);
 | 
			
		||||
                env->halted = 1;
 | 
			
		||||
                cs->halted = 1;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case PPC6xx_INPUT_HRESET:
 | 
			
		||||
            /* Level sensitive - active low */
 | 
			
		||||
            if (level) {
 | 
			
		||||
                LOG_IRQ("%s: reset the CPU\n", __func__);
 | 
			
		||||
                cpu_interrupt(env, CPU_INTERRUPT_RESET);
 | 
			
		||||
                cpu_interrupt(cs, CPU_INTERRUPT_RESET);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case PPC6xx_INPUT_SRESET:
 | 
			
		||||
@ -174,6 +178,8 @@ static void ppc970_set_irq(void *opaque, int pin, int level)
 | 
			
		||||
    cur_level = (env->irq_input_state >> pin) & 1;
 | 
			
		||||
    /* Don't generate spurious events */
 | 
			
		||||
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
 | 
			
		||||
        CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
        switch (pin) {
 | 
			
		||||
        case PPC970_INPUT_INT:
 | 
			
		||||
            /* Level sensitive - active high */
 | 
			
		||||
@ -203,17 +209,17 @@ static void ppc970_set_irq(void *opaque, int pin, int level)
 | 
			
		||||
            /* XXX: TODO: relay the signal to CKSTP_OUT pin */
 | 
			
		||||
            if (level) {
 | 
			
		||||
                LOG_IRQ("%s: stop the CPU\n", __func__);
 | 
			
		||||
                env->halted = 1;
 | 
			
		||||
                cs->halted = 1;
 | 
			
		||||
            } else {
 | 
			
		||||
                LOG_IRQ("%s: restart the CPU\n", __func__);
 | 
			
		||||
                env->halted = 0;
 | 
			
		||||
                qemu_cpu_kick(CPU(cpu));
 | 
			
		||||
                cs->halted = 0;
 | 
			
		||||
                qemu_cpu_kick(cs);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case PPC970_INPUT_HRESET:
 | 
			
		||||
            /* Level sensitive - active low */
 | 
			
		||||
            if (level) {
 | 
			
		||||
                cpu_interrupt(env, CPU_INTERRUPT_RESET);
 | 
			
		||||
                cpu_interrupt(cs, CPU_INTERRUPT_RESET);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case PPC970_INPUT_SRESET:
 | 
			
		||||
@ -295,6 +301,8 @@ static void ppc40x_set_irq(void *opaque, int pin, int level)
 | 
			
		||||
    cur_level = (env->irq_input_state >> pin) & 1;
 | 
			
		||||
    /* Don't generate spurious events */
 | 
			
		||||
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
 | 
			
		||||
        CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
        switch (pin) {
 | 
			
		||||
        case PPC40x_INPUT_RESET_SYS:
 | 
			
		||||
            if (level) {
 | 
			
		||||
@ -332,11 +340,11 @@ static void ppc40x_set_irq(void *opaque, int pin, int level)
 | 
			
		||||
            /* Level sensitive - active low */
 | 
			
		||||
            if (level) {
 | 
			
		||||
                LOG_IRQ("%s: stop the CPU\n", __func__);
 | 
			
		||||
                env->halted = 1;
 | 
			
		||||
                cs->halted = 1;
 | 
			
		||||
            } else {
 | 
			
		||||
                LOG_IRQ("%s: restart the CPU\n", __func__);
 | 
			
		||||
                env->halted = 0;
 | 
			
		||||
                qemu_cpu_kick(CPU(cpu));
 | 
			
		||||
                cs->halted = 0;
 | 
			
		||||
                qemu_cpu_kick(cs);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case PPC40x_INPUT_DEBUG:
 | 
			
		||||
 | 
			
		||||
@ -1776,7 +1776,7 @@ void ppc40x_core_reset(PowerPCCPU *cpu)
 | 
			
		||||
    target_ulong dbsr;
 | 
			
		||||
 | 
			
		||||
    printf("Reset PowerPC core\n");
 | 
			
		||||
    cpu_interrupt(env, CPU_INTERRUPT_RESET);
 | 
			
		||||
    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET);
 | 
			
		||||
    dbsr = env->spr[SPR_40x_DBSR];
 | 
			
		||||
    dbsr &= ~0x00000300;
 | 
			
		||||
    dbsr |= 0x00000100;
 | 
			
		||||
@ -1789,7 +1789,7 @@ void ppc40x_chip_reset(PowerPCCPU *cpu)
 | 
			
		||||
    target_ulong dbsr;
 | 
			
		||||
 | 
			
		||||
    printf("Reset PowerPC chip\n");
 | 
			
		||||
    cpu_interrupt(env, CPU_INTERRUPT_RESET);
 | 
			
		||||
    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET);
 | 
			
		||||
    /* XXX: TODO reset all internal peripherals */
 | 
			
		||||
    dbsr = env->spr[SPR_40x_DBSR];
 | 
			
		||||
    dbsr &= ~0x00000300;
 | 
			
		||||
 | 
			
		||||
@ -112,7 +112,7 @@ static void spin_kick(void *data)
 | 
			
		||||
    map_start = ldq_p(&curspin->addr) & ~(map_size - 1);
 | 
			
		||||
    mmubooke_create_initial_mapping(env, 0, map_start, map_size);
 | 
			
		||||
 | 
			
		||||
    env->halted = 0;
 | 
			
		||||
    cpu->halted = 0;
 | 
			
		||||
    env->exception_index = -1;
 | 
			
		||||
    cpu->stopped = false;
 | 
			
		||||
    qemu_cpu_kick(cpu);
 | 
			
		||||
 | 
			
		||||
@ -617,6 +617,8 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
 | 
			
		||||
 | 
			
		||||
static void ppc_spapr_reset(void)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *first_cpu_cpu;
 | 
			
		||||
 | 
			
		||||
    /* Reset the hash table & recalc the RMA */
 | 
			
		||||
    spapr_reset_htab(spapr);
 | 
			
		||||
 | 
			
		||||
@ -627,9 +629,10 @@ static void ppc_spapr_reset(void)
 | 
			
		||||
                       spapr->rtas_size);
 | 
			
		||||
 | 
			
		||||
    /* Set up the entry state */
 | 
			
		||||
    first_cpu_cpu = CPU(first_cpu);
 | 
			
		||||
    first_cpu->gpr[3] = spapr->fdt_addr;
 | 
			
		||||
    first_cpu->gpr[5] = 0;
 | 
			
		||||
    first_cpu->halted = 0;
 | 
			
		||||
    first_cpu_cpu->halted = 0;
 | 
			
		||||
    first_cpu->nip = spapr->entry_point;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -637,14 +640,15 @@ static void ppc_spapr_reset(void)
 | 
			
		||||
static void spapr_cpu_reset(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    PowerPCCPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUPPCState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    cpu_reset(CPU(cpu));
 | 
			
		||||
    cpu_reset(cs);
 | 
			
		||||
 | 
			
		||||
    /* All CPUs start halted.  CPU0 is unhalted from the machine level
 | 
			
		||||
     * reset code and the rest are explicitly started up by the guest
 | 
			
		||||
     * using an RTAS call */
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
 | 
			
		||||
    env->spr[SPR_HIOR] = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -543,7 +543,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 | 
			
		||||
    env->msr |= (1ULL << MSR_EE);
 | 
			
		||||
    hreg_compute_hflags(env);
 | 
			
		||||
    if (!cpu_has_work(cs)) {
 | 
			
		||||
        env->halted = 1;
 | 
			
		||||
        cs->halted = 1;
 | 
			
		||||
        env->exception_index = EXCP_HLT;
 | 
			
		||||
        cs->exit_request = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -145,7 +145,7 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (env->halted) {
 | 
			
		||||
        if (cpu->halted) {
 | 
			
		||||
            rtas_st(rets, 1, 0);
 | 
			
		||||
        } else {
 | 
			
		||||
            rtas_st(rets, 1, 2);
 | 
			
		||||
@ -184,7 +184,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!env->halted) {
 | 
			
		||||
        if (!cpu->halted) {
 | 
			
		||||
            rtas_st(rets, 0, -1);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@ -197,7 +197,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
 | 
			
		||||
        env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
 | 
			
		||||
        env->nip = start;
 | 
			
		||||
        env->gpr[3] = r3;
 | 
			
		||||
        env->halted = 0;
 | 
			
		||||
        cpu->halted = 0;
 | 
			
		||||
 | 
			
		||||
        qemu_cpu_kick(cpu);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -132,23 +132,25 @@ static unsigned s390_running_cpus;
 | 
			
		||||
 | 
			
		||||
void s390_add_running_cpu(S390CPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUS390XState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    if (env->halted) {
 | 
			
		||||
    if (cs->halted) {
 | 
			
		||||
        s390_running_cpus++;
 | 
			
		||||
        env->halted = 0;
 | 
			
		||||
        cs->halted = 0;
 | 
			
		||||
        env->exception_index = -1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned s390_del_running_cpu(S390CPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUS390XState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    if (env->halted == 0) {
 | 
			
		||||
    if (cs->halted == 0) {
 | 
			
		||||
        assert(s390_running_cpus >= 1);
 | 
			
		||||
        s390_running_cpus--;
 | 
			
		||||
        env->halted = 1;
 | 
			
		||||
        cs->halted = 1;
 | 
			
		||||
        env->exception_index = EXCP_HLT;
 | 
			
		||||
    }
 | 
			
		||||
    return s390_running_cpus;
 | 
			
		||||
@ -183,11 +185,13 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < smp_cpus; i++) {
 | 
			
		||||
        S390CPU *cpu;
 | 
			
		||||
        CPUState *cs;
 | 
			
		||||
 | 
			
		||||
        cpu = cpu_s390x_init(cpu_model);
 | 
			
		||||
        cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
        ipi_states[i] = cpu;
 | 
			
		||||
        cpu->env.halted = 1;
 | 
			
		||||
        cs->halted = 1;
 | 
			
		||||
        cpu->env.exception_index = EXCP_HLT;
 | 
			
		||||
        cpu->env.storage_keys = storage_keys;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -255,6 +255,7 @@ static uint32_t sh7750_mem_readw(void *opaque, hwaddr addr)
 | 
			
		||||
static uint32_t sh7750_mem_readl(void *opaque, hwaddr addr)
 | 
			
		||||
{
 | 
			
		||||
    SH7750State *s = opaque;
 | 
			
		||||
    SuperHCPUClass *scc;
 | 
			
		||||
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    case SH7750_BCR1_A7:
 | 
			
		||||
@ -288,11 +289,14 @@ static uint32_t sh7750_mem_readl(void *opaque, hwaddr addr)
 | 
			
		||||
    case SH7750_CCR_A7:
 | 
			
		||||
	return s->ccr;
 | 
			
		||||
    case 0x1f000030:		/* Processor version */
 | 
			
		||||
	return s->cpu->pvr;
 | 
			
		||||
        scc = SUPERH_CPU_GET_CLASS(s->cpu);
 | 
			
		||||
        return scc->pvr;
 | 
			
		||||
    case 0x1f000040:		/* Cache version */
 | 
			
		||||
	return s->cpu->cvr;
 | 
			
		||||
        scc = SUPERH_CPU_GET_CLASS(s->cpu);
 | 
			
		||||
        return scc->cvr;
 | 
			
		||||
    case 0x1f000044:		/* Processor revision */
 | 
			
		||||
	return s->cpu->prr;
 | 
			
		||||
        scc = SUPERH_CPU_GET_CLASS(s->cpu);
 | 
			
		||||
        return scc->prr;
 | 
			
		||||
    default:
 | 
			
		||||
	error_access("long read", addr);
 | 
			
		||||
        abort();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								hw/sh_intc.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								hw/sh_intc.c
									
									
									
									
									
								
							@ -42,15 +42,17 @@ void sh_intc_toggle_source(struct intc_source *source,
 | 
			
		||||
        pending_changed = 1;
 | 
			
		||||
 | 
			
		||||
    if (pending_changed) {
 | 
			
		||||
        CPUState *cpu = CPU(sh_env_get_cpu(first_cpu));
 | 
			
		||||
        if (source->pending) {
 | 
			
		||||
            source->parent->pending++;
 | 
			
		||||
	    if (source->parent->pending == 1)
 | 
			
		||||
                cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
 | 
			
		||||
            if (source->parent->pending == 1) {
 | 
			
		||||
                cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
 | 
			
		||||
            }
 | 
			
		||||
	else {
 | 
			
		||||
        } else {
 | 
			
		||||
            source->parent->pending--;
 | 
			
		||||
	    if (source->parent->pending == 0)
 | 
			
		||||
                cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
 | 
			
		||||
            if (source->parent->pending == 0) {
 | 
			
		||||
                cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
 | 
			
		||||
            }
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -49,11 +49,12 @@ typedef struct ResetData {
 | 
			
		||||
static void main_cpu_reset(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    ResetData *s   = (ResetData *)opaque;
 | 
			
		||||
    CPUState *cpu = CPU(s->cpu);
 | 
			
		||||
    CPUSPARCState  *env = &s->cpu->env;
 | 
			
		||||
 | 
			
		||||
    cpu_reset(CPU(s->cpu));
 | 
			
		||||
    cpu_reset(cpu);
 | 
			
		||||
 | 
			
		||||
    env->halted = 0;
 | 
			
		||||
    cpu->halted = 0;
 | 
			
		||||
    env->pc     = s->entry;
 | 
			
		||||
    env->npc    = s->entry + 4;
 | 
			
		||||
}
 | 
			
		||||
@ -66,6 +67,7 @@ void leon3_irq_ack(void *irq_manager, int intno)
 | 
			
		||||
static void leon3_set_pil_in(void *opaque, uint32_t pil_in)
 | 
			
		||||
{
 | 
			
		||||
    CPUSPARCState *env = (CPUSPARCState *)opaque;
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
 | 
			
		||||
    assert(env != NULL);
 | 
			
		||||
 | 
			
		||||
@ -81,16 +83,18 @@ static void leon3_set_pil_in(void *opaque, uint32_t pil_in)
 | 
			
		||||
 | 
			
		||||
                env->interrupt_index = TT_EXTINT | i;
 | 
			
		||||
                if (old_interrupt != env->interrupt_index) {
 | 
			
		||||
                    cs = CPU(sparc_env_get_cpu(env));
 | 
			
		||||
                    trace_leon3_set_irq(i);
 | 
			
		||||
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
                    cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
 | 
			
		||||
        cs = CPU(sparc_env_get_cpu(env));
 | 
			
		||||
        trace_leon3_reset_irq(env->interrupt_index & 15);
 | 
			
		||||
        env->interrupt_index = 0;
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -230,6 +230,8 @@ void sun4m_irq_info(Monitor *mon, const QDict *qdict)
 | 
			
		||||
 | 
			
		||||
void cpu_check_irqs(CPUSPARCState *env)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
 | 
			
		||||
    if (env->pil_in && (env->interrupt_index == 0 ||
 | 
			
		||||
                        (env->interrupt_index & ~15) == TT_EXTINT)) {
 | 
			
		||||
        unsigned int i;
 | 
			
		||||
@ -240,26 +242,29 @@ void cpu_check_irqs(CPUSPARCState *env)
 | 
			
		||||
 | 
			
		||||
                env->interrupt_index = TT_EXTINT | i;
 | 
			
		||||
                if (old_interrupt != env->interrupt_index) {
 | 
			
		||||
                    cs = CPU(sparc_env_get_cpu(env));
 | 
			
		||||
                    trace_sun4m_cpu_interrupt(i);
 | 
			
		||||
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
                    cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
 | 
			
		||||
        cs = CPU(sparc_env_get_cpu(env));
 | 
			
		||||
        trace_sun4m_cpu_reset_interrupt(env->interrupt_index & 15);
 | 
			
		||||
        env->interrupt_index = 0;
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_kick_irq(SPARCCPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUSPARCState *env = &cpu->env;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    env->halted = 0;
 | 
			
		||||
    cs->halted = 0;
 | 
			
		||||
    cpu_check_irqs(env);
 | 
			
		||||
    qemu_cpu_kick(CPU(cpu));
 | 
			
		||||
    qemu_cpu_kick(cs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_set_irq(void *opaque, int irq, int level)
 | 
			
		||||
@ -285,25 +290,27 @@ static void dummy_cpu_set_irq(void *opaque, int irq, int level)
 | 
			
		||||
static void main_cpu_reset(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    SPARCCPU *cpu = opaque;
 | 
			
		||||
    CPUSPARCState *env = &cpu->env;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    cpu_reset(CPU(cpu));
 | 
			
		||||
    env->halted = 0;
 | 
			
		||||
    cpu_reset(cs);
 | 
			
		||||
    cs->halted = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void secondary_cpu_reset(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    SPARCCPU *cpu = opaque;
 | 
			
		||||
    CPUSPARCState *env = &cpu->env;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    cpu_reset(CPU(cpu));
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    cpu_reset(cs);
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_halt_signal(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    if (level && cpu_single_env)
 | 
			
		||||
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
 | 
			
		||||
    if (level && cpu_single_env) {
 | 
			
		||||
        cpu_interrupt(CPU(sparc_env_get_cpu(cpu_single_env)),
 | 
			
		||||
                      CPU_INTERRUPT_HALT);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 | 
			
		||||
@ -826,6 +833,7 @@ static const TypeInfo ram_info = {
 | 
			
		||||
static void cpu_devinit(const char *cpu_model, unsigned int id,
 | 
			
		||||
                        uint64_t prom_addr, qemu_irq **cpu_irqs)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
    SPARCCPU *cpu;
 | 
			
		||||
    CPUSPARCState *env;
 | 
			
		||||
 | 
			
		||||
@ -841,7 +849,8 @@ static void cpu_devinit(const char *cpu_model, unsigned int id,
 | 
			
		||||
        qemu_register_reset(main_cpu_reset, cpu);
 | 
			
		||||
    } else {
 | 
			
		||||
        qemu_register_reset(secondary_cpu_reset, cpu);
 | 
			
		||||
        env->halted = 1;
 | 
			
		||||
        cs = CPU(cpu);
 | 
			
		||||
        cs->halted = 1;
 | 
			
		||||
    }
 | 
			
		||||
    *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, cpu, MAX_PILS);
 | 
			
		||||
    env->prom_addr = prom_addr;
 | 
			
		||||
 | 
			
		||||
@ -254,6 +254,7 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename,
 | 
			
		||||
 | 
			
		||||
void cpu_check_irqs(CPUSPARCState *env)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
    uint32_t pil = env->pil_in |
 | 
			
		||||
                  (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
 | 
			
		||||
 | 
			
		||||
@ -261,6 +262,7 @@ void cpu_check_irqs(CPUSPARCState *env)
 | 
			
		||||
    if (env->ivec_status & 0x20) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    cs = CPU(sparc_env_get_cpu(env));
 | 
			
		||||
    /* check if TM or SM in SOFTINT are set
 | 
			
		||||
       setting these also causes interrupt 14 */
 | 
			
		||||
    if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
 | 
			
		||||
@ -270,11 +272,11 @@ void cpu_check_irqs(CPUSPARCState *env)
 | 
			
		||||
    /* The bit corresponding to psrpil is (1<< psrpil), the next bit
 | 
			
		||||
       is (2 << psrpil). */
 | 
			
		||||
    if (pil < (2 << env->psrpil)){
 | 
			
		||||
        if (env->interrupt_request & CPU_INTERRUPT_HARD) {
 | 
			
		||||
        if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
 | 
			
		||||
            CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
 | 
			
		||||
                           env->interrupt_index);
 | 
			
		||||
            env->interrupt_index = 0;
 | 
			
		||||
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@ -297,50 +299,54 @@ void cpu_check_irqs(CPUSPARCState *env)
 | 
			
		||||
                    env->interrupt_index = new_interrupt;
 | 
			
		||||
                    CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i,
 | 
			
		||||
                                   old_interrupt, new_interrupt);
 | 
			
		||||
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
                    cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (env->interrupt_request & CPU_INTERRUPT_HARD) {
 | 
			
		||||
    } else if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
 | 
			
		||||
        CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
 | 
			
		||||
                       "current interrupt %x\n",
 | 
			
		||||
                       pil, env->pil_in, env->softint, env->interrupt_index);
 | 
			
		||||
        env->interrupt_index = 0;
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_kick_irq(SPARCCPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUSPARCState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->halted = 0;
 | 
			
		||||
    cs->halted = 0;
 | 
			
		||||
    cpu_check_irqs(env);
 | 
			
		||||
    qemu_cpu_kick(CPU(cpu));
 | 
			
		||||
    qemu_cpu_kick(cs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_set_ivec_irq(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    SPARCCPU *cpu = opaque;
 | 
			
		||||
    CPUSPARCState *env = &cpu->env;
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
 | 
			
		||||
    if (level) {
 | 
			
		||||
        if (!(env->ivec_status & 0x20)) {
 | 
			
		||||
            CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
 | 
			
		||||
            env->halted = 0;
 | 
			
		||||
            cs = CPU(cpu);
 | 
			
		||||
            cs->halted = 0;
 | 
			
		||||
            env->interrupt_index = TT_IVEC;
 | 
			
		||||
            env->ivec_status |= 0x20;
 | 
			
		||||
            env->ivec_data[0] = (0x1f << 6) | irq;
 | 
			
		||||
            env->ivec_data[1] = 0;
 | 
			
		||||
            env->ivec_data[2] = 0;
 | 
			
		||||
            cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if (env->ivec_status & 0x20) {
 | 
			
		||||
            CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
 | 
			
		||||
            cs = CPU(cpu);
 | 
			
		||||
            env->ivec_status &= ~0x20;
 | 
			
		||||
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,13 +26,14 @@
 | 
			
		||||
 | 
			
		||||
static void puv3_intc_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    CPUUniCore32State *env = opaque;
 | 
			
		||||
    UniCore32CPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    assert(irq == 0);
 | 
			
		||||
    if (level) {
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -44,7 +45,8 @@ static void puv3_soc_init(CPUUniCore32State *env)
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* Initialize interrupt controller */
 | 
			
		||||
    cpu_intc = qemu_allocate_irqs(puv3_intc_cpu_handler, env, 1);
 | 
			
		||||
    cpu_intc = qemu_allocate_irqs(puv3_intc_cpu_handler,
 | 
			
		||||
                                  uc32_env_get_cpu(env), 1);
 | 
			
		||||
    dev = sysbus_create_simple("puv3_intc", PUV3_INTC_BASE, *cpu_intc);
 | 
			
		||||
    for (i = 0; i < PUV3_IRQS_NR; i++) {
 | 
			
		||||
        irqs[i] = qdev_get_gpio_in(dev, i);
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,7 @@ void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d)
 | 
			
		||||
 | 
			
		||||
void check_interrupts(CPUXtensaState *env)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(xtensa_env_get_cpu(env));
 | 
			
		||||
    int minlevel = xtensa_get_cintlevel(env);
 | 
			
		||||
    uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE];
 | 
			
		||||
    int level;
 | 
			
		||||
@ -54,7 +55,7 @@ void check_interrupts(CPUXtensaState *env)
 | 
			
		||||
    /* If the CPU is halted advance CCOUNT according to the vm_clock time
 | 
			
		||||
     * elapsed since the moment when it was advanced last time.
 | 
			
		||||
     */
 | 
			
		||||
    if (env->halted) {
 | 
			
		||||
    if (cs->halted) {
 | 
			
		||||
        int64_t now = qemu_get_clock_ns(vm_clock);
 | 
			
		||||
 | 
			
		||||
        xtensa_advance_ccount(env,
 | 
			
		||||
@ -65,7 +66,7 @@ void check_interrupts(CPUXtensaState *env)
 | 
			
		||||
    for (level = env->config->nlevel; level > minlevel; --level) {
 | 
			
		||||
        if (env->config->level_mask[level] & int_set_enabled) {
 | 
			
		||||
            env->pending_irq_level = level;
 | 
			
		||||
            cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
            qemu_log_mask(CPU_LOG_INT,
 | 
			
		||||
                    "%s level = %d, cintlevel = %d, "
 | 
			
		||||
                    "pc = %08x, a0 = %08x, ps = %08x, "
 | 
			
		||||
@ -79,7 +80,7 @@ void check_interrupts(CPUXtensaState *env)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    env->pending_irq_level = 0;
 | 
			
		||||
    cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
    cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xtensa_set_irq(void *opaque, int irq, int active)
 | 
			
		||||
@ -127,11 +128,12 @@ static void xtensa_ccompare_cb(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    XtensaCPU *cpu = opaque;
 | 
			
		||||
    CPUXtensaState *env = &cpu->env;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    if (env->halted) {
 | 
			
		||||
    if (cs->halted) {
 | 
			
		||||
        env->halt_clock = qemu_get_clock_ns(vm_clock);
 | 
			
		||||
        xtensa_advance_ccount(env, env->wake_ccount - env->sregs[CCOUNT]);
 | 
			
		||||
        if (!cpu_has_work(CPU(cpu))) {
 | 
			
		||||
        if (!cpu_has_work(cs)) {
 | 
			
		||||
            env->sregs[CCOUNT] = env->wake_ccount + 1;
 | 
			
		||||
            xtensa_rearm_ccompare_timer(env);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -421,21 +421,6 @@ DECLARE_TLS(CPUArchState *,cpu_single_env);
 | 
			
		||||
     | CPU_INTERRUPT_TGT_EXT_3   \
 | 
			
		||||
     | CPU_INTERRUPT_TGT_EXT_4)
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
typedef void (*CPUInterruptHandler)(CPUArchState *, int);
 | 
			
		||||
 | 
			
		||||
extern CPUInterruptHandler cpu_interrupt_handler;
 | 
			
		||||
 | 
			
		||||
static inline void cpu_interrupt(CPUArchState *s, int mask)
 | 
			
		||||
{
 | 
			
		||||
    cpu_interrupt_handler(s, mask);
 | 
			
		||||
}
 | 
			
		||||
#else /* USER_ONLY */
 | 
			
		||||
void cpu_interrupt(CPUArchState *env, int mask);
 | 
			
		||||
#endif /* USER_ONLY */
 | 
			
		||||
 | 
			
		||||
void cpu_reset_interrupt(CPUArchState *env, int mask);
 | 
			
		||||
 | 
			
		||||
void cpu_exit(CPUArchState *s);
 | 
			
		||||
 | 
			
		||||
/* Breakpoint/watchpoint flags */
 | 
			
		||||
 | 
			
		||||
@ -156,8 +156,6 @@ typedef struct CPUWatchpoint {
 | 
			
		||||
                            accessed */                                 \
 | 
			
		||||
    target_ulong mem_io_vaddr; /* target virtual addr at which the      \
 | 
			
		||||
                                     memory was accessed */             \
 | 
			
		||||
    uint32_t halted; /* Nonzero if the CPU is in suspend state */       \
 | 
			
		||||
    uint32_t interrupt_request;                                         \
 | 
			
		||||
    CPU_COMMON_TLB                                                      \
 | 
			
		||||
    struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
 | 
			
		||||
    /* buffer for temporaries in the code generator */                  \
 | 
			
		||||
 | 
			
		||||
@ -134,6 +134,10 @@ struct VMStateDescription {
 | 
			
		||||
    const VMStateSubsection *subsections;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_USER_ONLY
 | 
			
		||||
extern const VMStateDescription vmstate_dummy;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern const VMStateInfo vmstate_info_bool;
 | 
			
		||||
 | 
			
		||||
extern const VMStateInfo vmstate_info_int8;
 | 
			
		||||
@ -638,12 +642,20 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
 | 
			
		||||
                       void *opaque, int version_id);
 | 
			
		||||
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
 | 
			
		||||
                        void *opaque);
 | 
			
		||||
int vmstate_register(DeviceState *dev, int instance_id,
 | 
			
		||||
                     const VMStateDescription *vmsd, void *base);
 | 
			
		||||
 | 
			
		||||
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
 | 
			
		||||
                                   const VMStateDescription *vmsd,
 | 
			
		||||
                                   void *base, int alias_id,
 | 
			
		||||
                                   int required_for_version);
 | 
			
		||||
 | 
			
		||||
static inline int vmstate_register(DeviceState *dev, int instance_id,
 | 
			
		||||
                                   const VMStateDescription *vmsd,
 | 
			
		||||
                                   void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    return vmstate_register_with_alias_id(dev, instance_id, vmsd,
 | 
			
		||||
                                          opaque, -1, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
 | 
			
		||||
                        void *opaque);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,8 @@ typedef struct CPUState CPUState;
 | 
			
		||||
 * @class_by_name: Callback to map -cpu command line model name to an
 | 
			
		||||
 * instantiatable CPU type.
 | 
			
		||||
 * @reset: Callback to reset the #CPUState to its initial state.
 | 
			
		||||
 * @do_interrupt: Callback for interrupt handling.
 | 
			
		||||
 * @vmsd: State description for migration.
 | 
			
		||||
 *
 | 
			
		||||
 * Represents a CPU family or model.
 | 
			
		||||
 */
 | 
			
		||||
@ -55,6 +57,9 @@ typedef struct CPUClass {
 | 
			
		||||
    ObjectClass *(*class_by_name)(const char *cpu_model);
 | 
			
		||||
 | 
			
		||||
    void (*reset)(CPUState *cpu);
 | 
			
		||||
    void (*do_interrupt)(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
    const struct VMStateDescription *vmsd;
 | 
			
		||||
} CPUClass;
 | 
			
		||||
 | 
			
		||||
struct KVMState;
 | 
			
		||||
@ -69,6 +74,8 @@ struct kvm_run;
 | 
			
		||||
 * @host_tid: Host thread ID.
 | 
			
		||||
 * @running: #true if CPU is currently running (usermode).
 | 
			
		||||
 * @created: Indicates whether the CPU thread has been successfully created.
 | 
			
		||||
 * @interrupt_request: Indicates a pending interrupt request.
 | 
			
		||||
 * @halted: Nonzero if the CPU is in suspended state.
 | 
			
		||||
 * @stop: Indicates a pending stop request.
 | 
			
		||||
 * @stopped: Indicates the CPU has been artificially stopped.
 | 
			
		||||
 * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
 | 
			
		||||
@ -103,6 +110,7 @@ struct CPUState {
 | 
			
		||||
    bool stopped;
 | 
			
		||||
    volatile sig_atomic_t exit_request;
 | 
			
		||||
    volatile sig_atomic_t tcg_exit_req;
 | 
			
		||||
    uint32_t interrupt_request;
 | 
			
		||||
 | 
			
		||||
    void *env_ptr; /* CPUArchState */
 | 
			
		||||
    struct TranslationBlock *current_tb;
 | 
			
		||||
@ -114,6 +122,7 @@ struct CPUState {
 | 
			
		||||
 | 
			
		||||
    /* TODO Move common fields from CPUArchState here. */
 | 
			
		||||
    int cpu_index; /* used by alpha TCG */
 | 
			
		||||
    uint32_t halted; /* used by alpha, cris, ppc TCG */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -134,6 +143,27 @@ void cpu_reset(CPUState *cpu);
 | 
			
		||||
 */
 | 
			
		||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cpu_class_set_vmsd:
 | 
			
		||||
 * @cc: CPU class
 | 
			
		||||
 * @value: Value to set. Unused for %CONFIG_USER_ONLY.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets #VMStateDescription for @cc.
 | 
			
		||||
 *
 | 
			
		||||
 * The @value argument is intentionally discarded for the non-softmmu targets
 | 
			
		||||
 * to avoid linker errors or excessive preprocessor usage. If this behavior
 | 
			
		||||
 * is undesired, you should assign #CPUState.vmsd directly instead.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
static inline void cpu_class_set_vmsd(CPUClass *cc,
 | 
			
		||||
                                      const struct VMStateDescription *value)
 | 
			
		||||
{
 | 
			
		||||
    cc->vmsd = value;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * qemu_cpu_has_work:
 | 
			
		||||
 * @cpu: The vCPU to check.
 | 
			
		||||
@ -193,5 +223,38 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
 | 
			
		||||
 */
 | 
			
		||||
CPUState *qemu_get_cpu(int index);
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
 | 
			
		||||
typedef void (*CPUInterruptHandler)(CPUState *, int);
 | 
			
		||||
 | 
			
		||||
extern CPUInterruptHandler cpu_interrupt_handler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cpu_interrupt:
 | 
			
		||||
 * @cpu: The CPU to set an interrupt on.
 | 
			
		||||
 * @mask: The interupts to set.
 | 
			
		||||
 *
 | 
			
		||||
 * Invokes the interrupt handler.
 | 
			
		||||
 */
 | 
			
		||||
static inline void cpu_interrupt(CPUState *cpu, int mask)
 | 
			
		||||
{
 | 
			
		||||
    cpu_interrupt_handler(cpu, mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else /* USER_ONLY */
 | 
			
		||||
 | 
			
		||||
void cpu_interrupt(CPUState *cpu, int mask);
 | 
			
		||||
 | 
			
		||||
#endif /* USER_ONLY */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cpu_reset_interrupt:
 | 
			
		||||
 * @cpu: The CPU to clear the interrupt on.
 | 
			
		||||
 * @mask: The interrupt mask to clear.
 | 
			
		||||
 *
 | 
			
		||||
 * Resets interrupts on the vCPU @cpu.
 | 
			
		||||
 */
 | 
			
		||||
void cpu_reset_interrupt(CPUState *cpu, int mask);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -826,11 +826,9 @@ static MemoryListener kvm_io_listener = {
 | 
			
		||||
    .priority = 10,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void kvm_handle_interrupt(CPUArchState *env, int mask)
 | 
			
		||||
static void kvm_handle_interrupt(CPUState *cpu, int mask)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cpu = ENV_GET_CPU(env);
 | 
			
		||||
 | 
			
		||||
    env->interrupt_request |= mask;
 | 
			
		||||
    cpu->interrupt_request |= mask;
 | 
			
		||||
 | 
			
		||||
    if (!qemu_cpu_is_self(cpu)) {
 | 
			
		||||
        qemu_cpu_kick(cpu);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								monitor.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								monitor.c
									
									
									
									
									
								
							@ -856,17 +856,14 @@ EventInfoList *qmp_query_events(Error **errp)
 | 
			
		||||
/* set the current CPU defined by the user */
 | 
			
		||||
int monitor_set_cpu(int cpu_index)
 | 
			
		||||
{
 | 
			
		||||
    CPUArchState *env;
 | 
			
		||||
    CPUState *cpu;
 | 
			
		||||
 | 
			
		||||
    for (env = first_cpu; env != NULL; env = env->next_cpu) {
 | 
			
		||||
        cpu = ENV_GET_CPU(env);
 | 
			
		||||
        if (cpu->cpu_index == cpu_index) {
 | 
			
		||||
            cur_mon->mon_cpu = env;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    cpu = qemu_get_cpu(cpu_index);
 | 
			
		||||
    if (cpu == NULL) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    cur_mon->mon_cpu = cpu->env_ptr;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CPUArchState *mon_get_cpu(void)
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,11 @@
 | 
			
		||||
#include "qom/cpu.h"
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
 | 
			
		||||
void cpu_reset_interrupt(CPUState *cpu, int mask)
 | 
			
		||||
{
 | 
			
		||||
    cpu->interrupt_request &= ~mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cpu_reset(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUClass *klass = CPU_GET_CLASS(cpu);
 | 
			
		||||
@ -33,7 +38,9 @@ void cpu_reset(CPUState *cpu)
 | 
			
		||||
static void cpu_common_reset(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    cpu->exit_request = 0;
 | 
			
		||||
    cpu->interrupt_request = 0;
 | 
			
		||||
    cpu->current_tb = NULL;
 | 
			
		||||
    cpu->halted = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								savevm.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								savevm.c
									
									
									
									
									
								
							@ -1423,13 +1423,6 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int vmstate_register(DeviceState *dev, int instance_id,
 | 
			
		||||
                     const VMStateDescription *vmsd, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    return vmstate_register_with_alias_id(dev, instance_id, vmsd,
 | 
			
		||||
                                          opaque, -1, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
 | 
			
		||||
                        void *opaque)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,8 @@
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
#include "migration/vmstate.h"
 | 
			
		||||
 | 
			
		||||
const VMStateDescription vmstate_dummy = {};
 | 
			
		||||
 | 
			
		||||
int vmstate_register_with_alias_id(DeviceState *dev,
 | 
			
		||||
                                   int instance_id,
 | 
			
		||||
                                   const VMStateDescription *vmsd,
 | 
			
		||||
 | 
			
		||||
@ -74,4 +74,6 @@ static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
 | 
			
		||||
 | 
			
		||||
#define ENV_OFFSET offsetof(AlphaCPU, env)
 | 
			
		||||
 | 
			
		||||
void alpha_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -263,6 +263,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
    dc->realize = alpha_cpu_realizefn;
 | 
			
		||||
 | 
			
		||||
    cc->class_by_name = alpha_cpu_class_by_name;
 | 
			
		||||
    cc->do_interrupt = alpha_cpu_do_interrupt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo alpha_cpu_type_info = {
 | 
			
		||||
 | 
			
		||||
@ -449,7 +449,6 @@ int cpu_alpha_signal_handler(int host_signum, void *pinfo,
 | 
			
		||||
int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
 | 
			
		||||
                                int mmu_idx);
 | 
			
		||||
#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
 | 
			
		||||
void do_interrupt (CPUAlphaState *env);
 | 
			
		||||
void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
 | 
			
		||||
void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
 | 
			
		||||
void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
 | 
			
		||||
@ -517,8 +516,6 @@ static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUAlphaState *env = &ALPHA_CPU(cpu)->env;
 | 
			
		||||
 | 
			
		||||
    /* Here we are checking to see if the CPU should wake up from HALT.
 | 
			
		||||
       We will have gotten into this state only for WTINT from PALmode.  */
 | 
			
		||||
    /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
 | 
			
		||||
@ -526,7 +523,7 @@ static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
       assume that if a CPU really wants to stay asleep, it will mask
 | 
			
		||||
       interrupts at the chipset level, which will prevent these bits
 | 
			
		||||
       from being set in the first place.  */
 | 
			
		||||
    return env->interrupt_request & (CPU_INTERRUPT_HARD
 | 
			
		||||
    return cpu->interrupt_request & (CPU_INTERRUPT_HARD
 | 
			
		||||
                                     | CPU_INTERRUPT_TIMER
 | 
			
		||||
                                     | CPU_INTERRUPT_SMP
 | 
			
		||||
                                     | CPU_INTERRUPT_MCHK);
 | 
			
		||||
 | 
			
		||||
@ -345,8 +345,10 @@ int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong addr, int rw,
 | 
			
		||||
}
 | 
			
		||||
#endif /* USER_ONLY */
 | 
			
		||||
 | 
			
		||||
void do_interrupt (CPUAlphaState *env)
 | 
			
		||||
void alpha_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    AlphaCPU *cpu = ALPHA_CPU(cs);
 | 
			
		||||
    CPUAlphaState *env = &cpu->env;
 | 
			
		||||
    int i = env->exception_index;
 | 
			
		||||
 | 
			
		||||
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
 | 
			
		||||
 | 
			
		||||
@ -1686,7 +1686,8 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
 | 
			
		||||
    case 253:
 | 
			
		||||
        /* WAIT */
 | 
			
		||||
        tmp = tcg_const_i64(1);
 | 
			
		||||
        tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUAlphaState, halted));
 | 
			
		||||
        tcg_gen_st32_i64(tmp, cpu_env, -offsetof(AlphaCPU, env) +
 | 
			
		||||
                                       offsetof(CPUState, halted));
 | 
			
		||||
        return gen_excp(ctx, EXCP_HLT, 0);
 | 
			
		||||
 | 
			
		||||
    case 252:
 | 
			
		||||
 | 
			
		||||
@ -113,4 +113,7 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
 | 
			
		||||
 | 
			
		||||
void register_cp_regs_for_features(ARMCPU *cpu);
 | 
			
		||||
 | 
			
		||||
void arm_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -412,6 +412,15 @@ static void cortex_m3_initfn(Object *obj)
 | 
			
		||||
    cpu->midr = 0x410fc231;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void arm_v7m_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
{
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
    CPUClass *cc = CPU_CLASS(oc);
 | 
			
		||||
 | 
			
		||||
    cc->do_interrupt = arm_v7m_cpu_do_interrupt;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
 | 
			
		||||
    { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
 | 
			
		||||
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
			
		||||
@ -752,6 +761,7 @@ static void arm_any_initfn(Object *obj)
 | 
			
		||||
typedef struct ARMCPUInfo {
 | 
			
		||||
    const char *name;
 | 
			
		||||
    void (*initfn)(Object *obj);
 | 
			
		||||
    void (*class_init)(ObjectClass *oc, void *data);
 | 
			
		||||
} ARMCPUInfo;
 | 
			
		||||
 | 
			
		||||
static const ARMCPUInfo arm_cpus[] = {
 | 
			
		||||
@ -766,7 +776,8 @@ static const ARMCPUInfo arm_cpus[] = {
 | 
			
		||||
    { .name = "arm1136",     .initfn = arm1136_initfn },
 | 
			
		||||
    { .name = "arm1176",     .initfn = arm1176_initfn },
 | 
			
		||||
    { .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
 | 
			
		||||
    { .name = "cortex-m3",   .initfn = cortex_m3_initfn },
 | 
			
		||||
    { .name = "cortex-m3",   .initfn = cortex_m3_initfn,
 | 
			
		||||
                             .class_init = arm_v7m_class_init },
 | 
			
		||||
    { .name = "cortex-a8",   .initfn = cortex_a8_initfn },
 | 
			
		||||
    { .name = "cortex-a9",   .initfn = cortex_a9_initfn },
 | 
			
		||||
    { .name = "cortex-a15",  .initfn = cortex_a15_initfn },
 | 
			
		||||
@ -802,6 +813,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
    cc->reset = arm_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->class_by_name = arm_cpu_class_by_name;
 | 
			
		||||
    cc->do_interrupt = arm_cpu_do_interrupt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_register(const ARMCPUInfo *info)
 | 
			
		||||
@ -811,6 +823,7 @@ static void cpu_register(const ARMCPUInfo *info)
 | 
			
		||||
        .instance_size = sizeof(ARMCPU),
 | 
			
		||||
        .instance_init = info->initfn,
 | 
			
		||||
        .class_size = sizeof(ARMCPUClass),
 | 
			
		||||
        .class_init = info->class_init,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
 | 
			
		||||
 | 
			
		||||
@ -236,7 +236,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model);
 | 
			
		||||
void arm_translate_init(void);
 | 
			
		||||
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
 | 
			
		||||
int cpu_arm_exec(CPUARMState *s);
 | 
			
		||||
void do_interrupt(CPUARMState *);
 | 
			
		||||
int bank_number(int mode);
 | 
			
		||||
void switch_mode(CPUARMState *, int);
 | 
			
		||||
uint32_t do_arm_semihosting(CPUARMState *env);
 | 
			
		||||
@ -722,9 +721,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUARMState *env = &ARM_CPU(cpu)->env;
 | 
			
		||||
 | 
			
		||||
    return env->interrupt_request &
 | 
			
		||||
    return cpu->interrupt_request &
 | 
			
		||||
        (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -764,7 +764,7 @@ static int omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                          uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    /* Wait-for-interrupt (deprecated) */
 | 
			
		||||
    cpu_interrupt(env, CPU_INTERRUPT_HALT);
 | 
			
		||||
    cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1567,8 +1567,11 @@ uint32_t HELPER(rbit)(uint32_t x)
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
void do_interrupt (CPUARMState *env)
 | 
			
		||||
void arm_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    ARMCPU *cpu = ARM_CPU(cs);
 | 
			
		||||
    CPUARMState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->exception_index = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1722,8 +1725,10 @@ static void do_v7m_exception_exit(CPUARMState *env)
 | 
			
		||||
       pointer.  */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_interrupt_v7m(CPUARMState *env)
 | 
			
		||||
void arm_v7m_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    ARMCPU *cpu = ARM_CPU(cs);
 | 
			
		||||
    CPUARMState *env = &cpu->env;
 | 
			
		||||
    uint32_t xpsr = xpsr_read(env);
 | 
			
		||||
    uint32_t lr;
 | 
			
		||||
    uint32_t addr;
 | 
			
		||||
@ -1799,17 +1804,17 @@ static void do_interrupt_v7m(CPUARMState *env)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle a CPU exception.  */
 | 
			
		||||
void do_interrupt(CPUARMState *env)
 | 
			
		||||
void arm_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    ARMCPU *cpu = ARM_CPU(cs);
 | 
			
		||||
    CPUARMState *env = &cpu->env;
 | 
			
		||||
    uint32_t addr;
 | 
			
		||||
    uint32_t mask;
 | 
			
		||||
    int new_mode;
 | 
			
		||||
    uint32_t offset;
 | 
			
		||||
 | 
			
		||||
    if (IS_M(env)) {
 | 
			
		||||
        do_interrupt_v7m(env);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    assert(!IS_M(env));
 | 
			
		||||
 | 
			
		||||
    /* TODO: Vectored interrupt controller.  */
 | 
			
		||||
    switch (env->exception_index) {
 | 
			
		||||
    case EXCP_UDEF:
 | 
			
		||||
@ -1907,7 +1912,7 @@ void do_interrupt(CPUARMState *env)
 | 
			
		||||
    }
 | 
			
		||||
    env->regs[14] = env->regs[15] + offset;
 | 
			
		||||
    env->regs[15] = addr;
 | 
			
		||||
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
 | 
			
		||||
    cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check section/page access permissions.
 | 
			
		||||
 | 
			
		||||
@ -218,8 +218,10 @@ uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
 | 
			
		||||
 | 
			
		||||
void HELPER(wfi)(CPUARMState *env)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(arm_env_get_cpu(env));
 | 
			
		||||
 | 
			
		||||
    env->exception_index = EXCP_HLT;
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
    cpu_loop_exit(env);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -73,4 +73,6 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
 | 
			
		||||
 | 
			
		||||
#define ENV_OFFSET offsetof(CRISCPU, env)
 | 
			
		||||
 | 
			
		||||
void cris_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -243,6 +243,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
    cc->reset = cris_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->class_by_name = cris_cpu_class_by_name;
 | 
			
		||||
    cc->do_interrupt = cris_cpu_do_interrupt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo cris_cpu_type_info = {
 | 
			
		||||
 | 
			
		||||
@ -175,7 +175,6 @@ typedef struct CPUCRISState {
 | 
			
		||||
 | 
			
		||||
CRISCPU *cpu_cris_init(const char *cpu_model);
 | 
			
		||||
int cpu_cris_exec(CPUCRISState *s);
 | 
			
		||||
void do_interrupt(CPUCRISState *env);
 | 
			
		||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
 | 
			
		||||
   signal handlers to inform the virtual CPU of exceptions. non zero
 | 
			
		||||
   is returned if the signal was handled by the virtual CPU.  */
 | 
			
		||||
@ -289,9 +288,7 @@ void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUCRISState *env = &CRIS_CPU(cpu)->env;
 | 
			
		||||
 | 
			
		||||
    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 | 
			
		||||
    return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "exec/exec-all.h"
 | 
			
		||||
 | 
			
		||||
@ -36,8 +36,11 @@
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
void do_interrupt (CPUCRISState *env)
 | 
			
		||||
void cris_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    CRISCPU *cpu = CRIS_CPU(cs);
 | 
			
		||||
    CPUCRISState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->exception_index = -1;
 | 
			
		||||
    env->pregs[PR_ERP] = env->pc;
 | 
			
		||||
}
 | 
			
		||||
@ -63,32 +66,31 @@ static void cris_shift_ccs(CPUCRISState *env)
 | 
			
		||||
    env->pregs[PR_CCS] = ccs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cpu_cris_handle_mmu_fault (CPUCRISState *env, target_ulong address, int rw,
 | 
			
		||||
int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
 | 
			
		||||
                              int mmu_idx)
 | 
			
		||||
{
 | 
			
		||||
    D(CPUState *cpu = CPU(cris_env_get_cpu(env)));
 | 
			
		||||
    struct cris_mmu_result res;
 | 
			
		||||
    int prot, miss;
 | 
			
		||||
    int r = -1;
 | 
			
		||||
    target_ulong phy;
 | 
			
		||||
 | 
			
		||||
	D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
 | 
			
		||||
    D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
 | 
			
		||||
    miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
 | 
			
		||||
                              rw, mmu_idx, 0);
 | 
			
		||||
	if (miss)
 | 
			
		||||
	{
 | 
			
		||||
		if (env->exception_index == EXCP_BUSFAULT)
 | 
			
		||||
    if (miss) {
 | 
			
		||||
        if (env->exception_index == EXCP_BUSFAULT) {
 | 
			
		||||
            cpu_abort(env,
 | 
			
		||||
                      "CRIS: Illegal recursive bus fault."
 | 
			
		||||
                      "addr=%x rw=%d\n",
 | 
			
		||||
                      address, rw);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        env->pregs[PR_EDA] = address;
 | 
			
		||||
        env->exception_index = EXCP_BUSFAULT;
 | 
			
		||||
        env->fault_vector = res.bf_vec;
 | 
			
		||||
        r = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
    } else {
 | 
			
		||||
        /*
 | 
			
		||||
         * Mask off the cache selection bit. The ETRAX busses do not
 | 
			
		||||
         * see the top bit.
 | 
			
		||||
@ -99,24 +101,25 @@ int cpu_cris_handle_mmu_fault (CPUCRISState *env, target_ulong address, int rw,
 | 
			
		||||
                     prot, mmu_idx, TARGET_PAGE_SIZE);
 | 
			
		||||
        r = 0;
 | 
			
		||||
    }
 | 
			
		||||
	if (r > 0)
 | 
			
		||||
    if (r > 0) {
 | 
			
		||||
        D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
 | 
			
		||||
                  __func__, r, env->interrupt_request, address, res.phy,
 | 
			
		||||
              __func__, r, cpu->interrupt_request, address, res.phy,
 | 
			
		||||
              res.bf_vec, env->pc);
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_interruptv10(CPUCRISState *env)
 | 
			
		||||
{
 | 
			
		||||
    D(CPUState *cs = CPU(cris_env_get_cpu(env)));
 | 
			
		||||
    int ex_vec = -1;
 | 
			
		||||
 | 
			
		||||
	D_LOG( "exception index=%d interrupt_req=%d\n",
 | 
			
		||||
    D_LOG("exception index=%d interrupt_req=%d\n",
 | 
			
		||||
          env->exception_index,
 | 
			
		||||
		   env->interrupt_request);
 | 
			
		||||
          cs->interrupt_request);
 | 
			
		||||
 | 
			
		||||
    assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
 | 
			
		||||
	switch (env->exception_index)
 | 
			
		||||
	{
 | 
			
		||||
    switch (env->exception_index) {
 | 
			
		||||
    case EXCP_BREAK:
 | 
			
		||||
        /* These exceptions are genereated by the core itself.
 | 
			
		||||
           ERP should point to the insn following the brk.  */
 | 
			
		||||
@ -162,19 +165,21 @@ static void do_interruptv10(CPUCRISState *env)
 | 
			
		||||
                  env->pregs[PR_ERP]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUCRISState *env)
 | 
			
		||||
void cris_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    CRISCPU *cpu = CRIS_CPU(cs);
 | 
			
		||||
    CPUCRISState *env = &cpu->env;
 | 
			
		||||
    int ex_vec = -1;
 | 
			
		||||
 | 
			
		||||
	if (env->pregs[PR_VR] < 32)
 | 
			
		||||
    if (env->pregs[PR_VR] < 32) {
 | 
			
		||||
        return do_interruptv10(env);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	D_LOG( "exception index=%d interrupt_req=%d\n",
 | 
			
		||||
    D_LOG("exception index=%d interrupt_req=%d\n",
 | 
			
		||||
          env->exception_index,
 | 
			
		||||
		   env->interrupt_request);
 | 
			
		||||
          cs->interrupt_request);
 | 
			
		||||
 | 
			
		||||
	switch (env->exception_index)
 | 
			
		||||
	{
 | 
			
		||||
    switch (env->exception_index) {
 | 
			
		||||
    case EXCP_BREAK:
 | 
			
		||||
        /* These exceptions are genereated by the core itself.
 | 
			
		||||
           ERP should point to the insn following the brk.  */
 | 
			
		||||
@ -258,8 +263,9 @@ hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr)
 | 
			
		||||
        miss = cris_mmu_translate(&res, env, addr, 2, 0, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	if (!miss)
 | 
			
		||||
    if (!miss) {
 | 
			
		||||
        phy = res.phy;
 | 
			
		||||
    }
 | 
			
		||||
    D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
 | 
			
		||||
    return phy;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2888,7 +2888,8 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
 | 
			
		||||
    cris_cc_mask(dc, 0);
 | 
			
		||||
 | 
			
		||||
    if (dc->op2 == 15) {
 | 
			
		||||
        t_gen_mov_env_TN(halted, tcg_const_tl(1));
 | 
			
		||||
        tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
 | 
			
		||||
                       -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
 | 
			
		||||
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
 | 
			
		||||
        t_gen_raise_exception(EXCP_HLT);
 | 
			
		||||
        return 2;
 | 
			
		||||
 | 
			
		||||
@ -76,4 +76,14 @@ static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
 | 
			
		||||
 | 
			
		||||
#define ENV_OFFSET offsetof(X86CPU, env)
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
extern const struct VMStateDescription vmstate_x86_cpu;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * x86_cpu_do_interrupt:
 | 
			
		||||
 * @cpu: vCPU the interrupt is to be handled by.
 | 
			
		||||
 */
 | 
			
		||||
void x86_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -2014,7 +2014,7 @@ static void x86_cpu_reset(CPUState *s)
 | 
			
		||||
        apic_designate_bsp(env->apic_state);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    env->halted = !cpu_is_bsp(cpu);
 | 
			
		||||
    s->halted = !cpu_is_bsp(cpu);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2250,6 +2250,9 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
 | 
			
		||||
    xcc->parent_reset = cc->reset;
 | 
			
		||||
    cc->reset = x86_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->do_interrupt = x86_cpu_do_interrupt;
 | 
			
		||||
    cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo x86_cpu_type_info = {
 | 
			
		||||
 | 
			
		||||
@ -967,6 +967,7 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
 | 
			
		||||
static inline void cpu_x86_load_seg_cache_sipi(X86CPU *cpu,
 | 
			
		||||
                                               int sipi_vector)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->eip = 0;
 | 
			
		||||
@ -974,7 +975,7 @@ static inline void cpu_x86_load_seg_cache_sipi(X86CPU *cpu,
 | 
			
		||||
                           sipi_vector << 12,
 | 
			
		||||
                           env->segs[R_CS].limit,
 | 
			
		||||
                           env->segs[R_CS].flags);
 | 
			
		||||
    env->halted = 0;
 | 
			
		||||
    cs->halted = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
 | 
			
		||||
@ -1092,8 +1093,6 @@ static inline CPUX86State *cpu_init(const char *cpu_model)
 | 
			
		||||
#define cpu_list x86_cpu_list
 | 
			
		||||
#define cpudef_setup	x86_cpudef_setup
 | 
			
		||||
 | 
			
		||||
#define CPU_SAVE_VERSION 12
 | 
			
		||||
 | 
			
		||||
/* MMU modes definitions */
 | 
			
		||||
#define MMU_MODE0_SUFFIX _kernel
 | 
			
		||||
#define MMU_MODE1_SUFFIX _user
 | 
			
		||||
@ -1168,14 +1167,15 @@ static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
 | 
			
		||||
#include "hw/apic.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = &X86_CPU(cpu)->env;
 | 
			
		||||
    X86CPU *cpu = X86_CPU(cs);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    return ((env->interrupt_request & (CPU_INTERRUPT_HARD |
 | 
			
		||||
    return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
 | 
			
		||||
                                      CPU_INTERRUPT_POLL)) &&
 | 
			
		||||
            (env->eflags & IF_MASK)) ||
 | 
			
		||||
           (env->interrupt_request & (CPU_INTERRUPT_NMI |
 | 
			
		||||
           (cs->interrupt_request & (CPU_INTERRUPT_NMI |
 | 
			
		||||
                                     CPU_INTERRUPT_INIT |
 | 
			
		||||
                                     CPU_INTERRUPT_SIPI |
 | 
			
		||||
                                     CPU_INTERRUPT_MCE));
 | 
			
		||||
@ -1252,8 +1252,7 @@ void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
 | 
			
		||||
                                   uint64_t param);
 | 
			
		||||
void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
 | 
			
		||||
 | 
			
		||||
/* op_helper.c */
 | 
			
		||||
void do_interrupt(CPUX86State *env);
 | 
			
		||||
/* seg_helper.c */
 | 
			
		||||
void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
 | 
			
		||||
 | 
			
		||||
void do_smm_enter(CPUX86State *env1);
 | 
			
		||||
 | 
			
		||||
@ -182,6 +182,7 @@ done:
 | 
			
		||||
void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
 | 
			
		||||
                    int flags)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(x86_env_get_cpu(env));
 | 
			
		||||
    int eflags, i, nb;
 | 
			
		||||
    char cc_op_name[32];
 | 
			
		||||
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
 | 
			
		||||
@ -225,7 +226,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
 | 
			
		||||
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
 | 
			
		||||
                    (env->a20_mask >> 20) & 1,
 | 
			
		||||
                    (env->hflags >> HF_SMM_SHIFT) & 1,
 | 
			
		||||
                    env->halted);
 | 
			
		||||
                    cs->halted);
 | 
			
		||||
    } else
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
@ -252,7 +253,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
 | 
			
		||||
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
 | 
			
		||||
                    (env->a20_mask >> 20) & 1,
 | 
			
		||||
                    (env->hflags >> HF_SMM_SHIFT) & 1,
 | 
			
		||||
                    env->halted);
 | 
			
		||||
                    cs->halted);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(i = 0; i < 6; i++) {
 | 
			
		||||
@ -388,7 +389,7 @@ void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
 | 
			
		||||
#endif
 | 
			
		||||
        /* if the cpu is currently executing code, we must unlink it and
 | 
			
		||||
           all the potentially executing TB */
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
 | 
			
		||||
        cpu_interrupt(CPU(cpu), CPU_INTERRUPT_EXITTB);
 | 
			
		||||
 | 
			
		||||
        /* when a20 is changed, all the MMU mappings are invalid, so
 | 
			
		||||
           we must flush everything */
 | 
			
		||||
@ -1168,7 +1169,7 @@ static void do_inject_x86_mce(void *data)
 | 
			
		||||
        banks[3] = params->misc;
 | 
			
		||||
        cenv->mcg_status = params->mcg_status;
 | 
			
		||||
        banks[1] = params->status;
 | 
			
		||||
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
 | 
			
		||||
        cpu_interrupt(cpu, CPU_INTERRUPT_MCE);
 | 
			
		||||
    } else if (!(banks[1] & MCI_STATUS_VAL)
 | 
			
		||||
               || !(banks[1] & MCI_STATUS_UC)) {
 | 
			
		||||
        if (banks[1] & MCI_STATUS_VAL) {
 | 
			
		||||
@ -1240,7 +1241,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
 | 
			
		||||
    if (kvm_enabled()) {
 | 
			
		||||
        env->tpr_access_type = access;
 | 
			
		||||
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_TPR);
 | 
			
		||||
        cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_TPR);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_restore_state(env, env->mem_io_pc);
 | 
			
		||||
 | 
			
		||||
@ -1281,12 +1282,13 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
void do_cpu_init(X86CPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
 | 
			
		||||
    int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
 | 
			
		||||
    uint64_t pat = env->pat;
 | 
			
		||||
 | 
			
		||||
    cpu_reset(CPU(cpu));
 | 
			
		||||
    env->interrupt_request = sipi;
 | 
			
		||||
    cpu_reset(cs);
 | 
			
		||||
    cs->interrupt_request = sipi;
 | 
			
		||||
    env->pat = pat;
 | 
			
		||||
    apic_init_reset(env->apic_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1460,17 +1460,18 @@ static int kvm_put_mp_state(X86CPU *cpu)
 | 
			
		||||
 | 
			
		||||
static int kvm_get_mp_state(X86CPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
    struct kvm_mp_state mp_state;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MP_STATE, &mp_state);
 | 
			
		||||
    ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    env->mp_state = mp_state.mp_state;
 | 
			
		||||
    if (kvm_irqchip_in_kernel()) {
 | 
			
		||||
        env->halted = (mp_state.mp_state == KVM_MP_STATE_HALTED);
 | 
			
		||||
        cs->halted = (mp_state.mp_state == KVM_MP_STATE_HALTED);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -1762,8 +1763,8 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    /* Inject NMI */
 | 
			
		||||
    if (env->interrupt_request & CPU_INTERRUPT_NMI) {
 | 
			
		||||
        env->interrupt_request &= ~CPU_INTERRUPT_NMI;
 | 
			
		||||
    if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
 | 
			
		||||
        cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
 | 
			
		||||
        DPRINTF("injected NMI\n");
 | 
			
		||||
        ret = kvm_vcpu_ioctl(cpu, KVM_NMI);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
@ -1775,18 +1776,18 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
 | 
			
		||||
    if (!kvm_irqchip_in_kernel()) {
 | 
			
		||||
        /* Force the VCPU out of its inner loop to process any INIT requests
 | 
			
		||||
         * or pending TPR access reports. */
 | 
			
		||||
        if (env->interrupt_request &
 | 
			
		||||
        if (cpu->interrupt_request &
 | 
			
		||||
            (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
 | 
			
		||||
            cpu->exit_request = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Try to inject an interrupt if the guest can accept it */
 | 
			
		||||
        if (run->ready_for_interrupt_injection &&
 | 
			
		||||
            (env->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
            (cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
            (env->eflags & IF_MASK)) {
 | 
			
		||||
            int irq;
 | 
			
		||||
 | 
			
		||||
            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
			
		||||
            cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
 | 
			
		||||
            irq = cpu_get_pic_interrupt(env);
 | 
			
		||||
            if (irq >= 0) {
 | 
			
		||||
                struct kvm_interrupt intr;
 | 
			
		||||
@ -1806,7 +1807,7 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
 | 
			
		||||
         * interrupt, request an interrupt window exit.  This will
 | 
			
		||||
         * cause a return to userspace as soon as the guest is ready to
 | 
			
		||||
         * receive interrupts. */
 | 
			
		||||
        if ((env->interrupt_request & CPU_INTERRUPT_HARD)) {
 | 
			
		||||
        if ((cpu->interrupt_request & CPU_INTERRUPT_HARD)) {
 | 
			
		||||
            run->request_interrupt_window = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            run->request_interrupt_window = 0;
 | 
			
		||||
@ -1836,11 +1837,11 @@ int kvm_arch_process_async_events(CPUState *cs)
 | 
			
		||||
    X86CPU *cpu = X86_CPU(cs);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    if (env->interrupt_request & CPU_INTERRUPT_MCE) {
 | 
			
		||||
    if (cs->interrupt_request & CPU_INTERRUPT_MCE) {
 | 
			
		||||
        /* We must not raise CPU_INTERRUPT_MCE if it's not supported. */
 | 
			
		||||
        assert(env->mcg_cap);
 | 
			
		||||
 | 
			
		||||
        env->interrupt_request &= ~CPU_INTERRUPT_MCE;
 | 
			
		||||
        cs->interrupt_request &= ~CPU_INTERRUPT_MCE;
 | 
			
		||||
 | 
			
		||||
        kvm_cpu_synchronize_state(env);
 | 
			
		||||
 | 
			
		||||
@ -1853,7 +1854,7 @@ int kvm_arch_process_async_events(CPUState *cs)
 | 
			
		||||
        env->exception_injected = EXCP12_MCHK;
 | 
			
		||||
        env->has_error_code = 0;
 | 
			
		||||
 | 
			
		||||
        env->halted = 0;
 | 
			
		||||
        cs->halted = 0;
 | 
			
		||||
        if (kvm_irqchip_in_kernel() && env->mp_state == KVM_MP_STATE_HALTED) {
 | 
			
		||||
            env->mp_state = KVM_MP_STATE_RUNNABLE;
 | 
			
		||||
        }
 | 
			
		||||
@ -1863,41 +1864,42 @@ int kvm_arch_process_async_events(CPUState *cs)
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (env->interrupt_request & CPU_INTERRUPT_POLL) {
 | 
			
		||||
        env->interrupt_request &= ~CPU_INTERRUPT_POLL;
 | 
			
		||||
    if (cs->interrupt_request & CPU_INTERRUPT_POLL) {
 | 
			
		||||
        cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
 | 
			
		||||
        apic_poll_irq(env->apic_state);
 | 
			
		||||
    }
 | 
			
		||||
    if (((env->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
    if (((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
         (env->eflags & IF_MASK)) ||
 | 
			
		||||
        (env->interrupt_request & CPU_INTERRUPT_NMI)) {
 | 
			
		||||
        env->halted = 0;
 | 
			
		||||
        (cs->interrupt_request & CPU_INTERRUPT_NMI)) {
 | 
			
		||||
        cs->halted = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (env->interrupt_request & CPU_INTERRUPT_INIT) {
 | 
			
		||||
    if (cs->interrupt_request & CPU_INTERRUPT_INIT) {
 | 
			
		||||
        kvm_cpu_synchronize_state(env);
 | 
			
		||||
        do_cpu_init(cpu);
 | 
			
		||||
    }
 | 
			
		||||
    if (env->interrupt_request & CPU_INTERRUPT_SIPI) {
 | 
			
		||||
    if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
 | 
			
		||||
        kvm_cpu_synchronize_state(env);
 | 
			
		||||
        do_cpu_sipi(cpu);
 | 
			
		||||
    }
 | 
			
		||||
    if (env->interrupt_request & CPU_INTERRUPT_TPR) {
 | 
			
		||||
        env->interrupt_request &= ~CPU_INTERRUPT_TPR;
 | 
			
		||||
    if (cs->interrupt_request & CPU_INTERRUPT_TPR) {
 | 
			
		||||
        cs->interrupt_request &= ~CPU_INTERRUPT_TPR;
 | 
			
		||||
        kvm_cpu_synchronize_state(env);
 | 
			
		||||
        apic_handle_tpr_access_report(env->apic_state, env->eip,
 | 
			
		||||
                                      env->tpr_access_type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return env->halted;
 | 
			
		||||
    return cs->halted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int kvm_handle_halt(X86CPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    if (!((env->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
    if (!((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
          (env->eflags & IF_MASK)) &&
 | 
			
		||||
        !(env->interrupt_request & CPU_INTERRUPT_NMI)) {
 | 
			
		||||
        env->halted = 1;
 | 
			
		||||
        !(cs->interrupt_request & CPU_INTERRUPT_NMI)) {
 | 
			
		||||
        cs->halted = 1;
 | 
			
		||||
        return EXCP_HLT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -171,14 +171,16 @@ static const VMStateInfo vmstate_fpreg_1_no_mmx = {
 | 
			
		||||
 | 
			
		||||
static bool fpregs_is_0(void *opaque, int version_id)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    return (env->fpregs_format_vmstate == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool fpregs_is_1_mmx(void *opaque, int version_id)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
    int guess_mmx;
 | 
			
		||||
 | 
			
		||||
    guess_mmx = ((env->fptag_vmstate == 0xff) &&
 | 
			
		||||
@ -188,7 +190,8 @@ static bool fpregs_is_1_mmx(void *opaque, int version_id)
 | 
			
		||||
 | 
			
		||||
static bool fpregs_is_1_no_mmx(void *opaque, int version_id)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
    int guess_mmx;
 | 
			
		||||
 | 
			
		||||
    guess_mmx = ((env->fptag_vmstate == 0xff) &&
 | 
			
		||||
@ -237,7 +240,8 @@ static const VMStateInfo vmstate_hack_uint64_as_uint32 = {
 | 
			
		||||
 | 
			
		||||
static void cpu_pre_save(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* FPU */
 | 
			
		||||
@ -252,7 +256,8 @@ static void cpu_pre_save(void *opaque)
 | 
			
		||||
 | 
			
		||||
static int cpu_post_load(void *opaque, int version_id)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* XXX: restore FPU round state */
 | 
			
		||||
@ -275,16 +280,16 @@ static int cpu_post_load(void *opaque, int version_id)
 | 
			
		||||
 | 
			
		||||
static bool async_pf_msr_needed(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *cpu = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
 | 
			
		||||
    return cpu->async_pf_en_msr != 0;
 | 
			
		||||
    return cpu->env.async_pf_en_msr != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool pv_eoi_msr_needed(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *cpu = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
 | 
			
		||||
    return cpu->pv_eoi_en_msr != 0;
 | 
			
		||||
    return cpu->env.pv_eoi_en_msr != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const VMStateDescription vmstate_async_pf_msr = {
 | 
			
		||||
@ -293,7 +298,7 @@ static const VMStateDescription vmstate_async_pf_msr = {
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField []) {
 | 
			
		||||
        VMSTATE_UINT64(async_pf_en_msr, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(env.async_pf_en_msr, X86CPU),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@ -304,14 +309,15 @@ static const VMStateDescription vmstate_pv_eoi_msr = {
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField []) {
 | 
			
		||||
        VMSTATE_UINT64(pv_eoi_en_msr, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool fpop_ip_dp_needed(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0;
 | 
			
		||||
}
 | 
			
		||||
@ -322,16 +328,17 @@ static const VMStateDescription vmstate_fpop_ip_dp = {
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField []) {
 | 
			
		||||
        VMSTATE_UINT16(fpop, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(fpip, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(fpdp, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT16(env.fpop, X86CPU),
 | 
			
		||||
        VMSTATE_UINT64(env.fpip, X86CPU),
 | 
			
		||||
        VMSTATE_UINT64(env.fpdp, X86CPU),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool tsc_adjust_needed(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    return env->tsc_adjust != 0;
 | 
			
		||||
}
 | 
			
		||||
@ -342,14 +349,15 @@ static const VMStateDescription vmstate_msr_tsc_adjust = {
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField[]) {
 | 
			
		||||
        VMSTATE_UINT64(tsc_adjust, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(env.tsc_adjust, X86CPU),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool tscdeadline_needed(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    return env->tsc_deadline != 0;
 | 
			
		||||
}
 | 
			
		||||
@ -360,14 +368,15 @@ static const VMStateDescription vmstate_msr_tscdeadline = {
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField []) {
 | 
			
		||||
        VMSTATE_UINT64(tsc_deadline, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(env.tsc_deadline, X86CPU),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool misc_enable_needed(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CPUX86State *env = opaque;
 | 
			
		||||
    X86CPU *cpu = opaque;
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT;
 | 
			
		||||
}
 | 
			
		||||
@ -378,111 +387,111 @@ static const VMStateDescription vmstate_msr_ia32_misc_enable = {
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField []) {
 | 
			
		||||
        VMSTATE_UINT64(msr_ia32_misc_enable, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const VMStateDescription vmstate_cpu = {
 | 
			
		||||
const VMStateDescription vmstate_x86_cpu = {
 | 
			
		||||
    .name = "cpu",
 | 
			
		||||
    .version_id = CPU_SAVE_VERSION,
 | 
			
		||||
    .version_id = 12,
 | 
			
		||||
    .minimum_version_id = 3,
 | 
			
		||||
    .minimum_version_id_old = 3,
 | 
			
		||||
    .pre_save = cpu_pre_save,
 | 
			
		||||
    .post_load = cpu_post_load,
 | 
			
		||||
    .fields      = (VMStateField []) {
 | 
			
		||||
        VMSTATE_UINTTL_ARRAY(regs, CPUX86State, CPU_NB_REGS),
 | 
			
		||||
        VMSTATE_UINTTL(eip, CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL(eflags, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT32(hflags, CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS),
 | 
			
		||||
        VMSTATE_UINTTL(env.eip, X86CPU),
 | 
			
		||||
        VMSTATE_UINTTL(env.eflags, X86CPU),
 | 
			
		||||
        VMSTATE_UINT32(env.hflags, X86CPU),
 | 
			
		||||
        /* FPU */
 | 
			
		||||
        VMSTATE_UINT16(fpuc, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT16(fpus_vmstate, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT16(fptag_vmstate, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT16(fpregs_format_vmstate, CPUX86State),
 | 
			
		||||
        VMSTATE_FP_REGS(fpregs, CPUX86State, 8),
 | 
			
		||||
        VMSTATE_UINT16(env.fpuc, X86CPU),
 | 
			
		||||
        VMSTATE_UINT16(env.fpus_vmstate, X86CPU),
 | 
			
		||||
        VMSTATE_UINT16(env.fptag_vmstate, X86CPU),
 | 
			
		||||
        VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU),
 | 
			
		||||
        VMSTATE_FP_REGS(env.fpregs, X86CPU, 8),
 | 
			
		||||
 | 
			
		||||
        VMSTATE_SEGMENT_ARRAY(segs, CPUX86State, 6),
 | 
			
		||||
        VMSTATE_SEGMENT(ldt, CPUX86State),
 | 
			
		||||
        VMSTATE_SEGMENT(tr, CPUX86State),
 | 
			
		||||
        VMSTATE_SEGMENT(gdt, CPUX86State),
 | 
			
		||||
        VMSTATE_SEGMENT(idt, CPUX86State),
 | 
			
		||||
        VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6),
 | 
			
		||||
        VMSTATE_SEGMENT(env.ldt, X86CPU),
 | 
			
		||||
        VMSTATE_SEGMENT(env.tr, X86CPU),
 | 
			
		||||
        VMSTATE_SEGMENT(env.gdt, X86CPU),
 | 
			
		||||
        VMSTATE_SEGMENT(env.idt, X86CPU),
 | 
			
		||||
 | 
			
		||||
        VMSTATE_UINT32(sysenter_cs, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT32(env.sysenter_cs, X86CPU),
 | 
			
		||||
#ifdef TARGET_X86_64
 | 
			
		||||
        /* Hack: In v7 size changed from 32 to 64 bits on x86_64 */
 | 
			
		||||
        VMSTATE_HACK_UINT32(sysenter_esp, CPUX86State, less_than_7),
 | 
			
		||||
        VMSTATE_HACK_UINT32(sysenter_eip, CPUX86State, less_than_7),
 | 
			
		||||
        VMSTATE_UINTTL_V(sysenter_esp, CPUX86State, 7),
 | 
			
		||||
        VMSTATE_UINTTL_V(sysenter_eip, CPUX86State, 7),
 | 
			
		||||
        VMSTATE_HACK_UINT32(env.sysenter_esp, X86CPU, less_than_7),
 | 
			
		||||
        VMSTATE_HACK_UINT32(env.sysenter_eip, X86CPU, less_than_7),
 | 
			
		||||
        VMSTATE_UINTTL_V(env.sysenter_esp, X86CPU, 7),
 | 
			
		||||
        VMSTATE_UINTTL_V(env.sysenter_eip, X86CPU, 7),
 | 
			
		||||
#else
 | 
			
		||||
        VMSTATE_UINTTL(sysenter_esp, CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL(sysenter_eip, CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL(env.sysenter_esp, X86CPU),
 | 
			
		||||
        VMSTATE_UINTTL(env.sysenter_eip, X86CPU),
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        VMSTATE_UINTTL(cr[0], CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL(cr[2], CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL(cr[3], CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL(cr[4], CPUX86State),
 | 
			
		||||
        VMSTATE_UINTTL_ARRAY(dr, CPUX86State, 8),
 | 
			
		||||
        VMSTATE_UINTTL(env.cr[0], X86CPU),
 | 
			
		||||
        VMSTATE_UINTTL(env.cr[2], X86CPU),
 | 
			
		||||
        VMSTATE_UINTTL(env.cr[3], X86CPU),
 | 
			
		||||
        VMSTATE_UINTTL(env.cr[4], X86CPU),
 | 
			
		||||
        VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8),
 | 
			
		||||
        /* MMU */
 | 
			
		||||
        VMSTATE_INT32(a20_mask, CPUX86State),
 | 
			
		||||
        VMSTATE_INT32(env.a20_mask, X86CPU),
 | 
			
		||||
        /* XMM */
 | 
			
		||||
        VMSTATE_UINT32(mxcsr, CPUX86State),
 | 
			
		||||
        VMSTATE_XMM_REGS(xmm_regs, CPUX86State, CPU_NB_REGS),
 | 
			
		||||
        VMSTATE_UINT32(env.mxcsr, X86CPU),
 | 
			
		||||
        VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, CPU_NB_REGS),
 | 
			
		||||
 | 
			
		||||
#ifdef TARGET_X86_64
 | 
			
		||||
        VMSTATE_UINT64(efer, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(star, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(lstar, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(cstar, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(fmask, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(kernelgsbase, CPUX86State),
 | 
			
		||||
        VMSTATE_UINT64(env.efer, X86CPU),
 | 
			
		||||
        VMSTATE_UINT64(env.star, X86CPU),
 | 
			
		||||
        VMSTATE_UINT64(env.lstar, X86CPU),
 | 
			
		||||
        VMSTATE_UINT64(env.cstar, X86CPU),
 | 
			
		||||
        VMSTATE_UINT64(env.fmask, X86CPU),
 | 
			
		||||
        VMSTATE_UINT64(env.kernelgsbase, X86CPU),
 | 
			
		||||
#endif
 | 
			
		||||
        VMSTATE_UINT32_V(smbase, CPUX86State, 4),
 | 
			
		||||
        VMSTATE_UINT32_V(env.smbase, X86CPU, 4),
 | 
			
		||||
 | 
			
		||||
        VMSTATE_UINT64_V(pat, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT32_V(hflags2, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT64_V(env.pat, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT32_V(env.hflags2, X86CPU, 5),
 | 
			
		||||
 | 
			
		||||
        VMSTATE_UINT32_TEST(halted, CPUX86State, version_is_5),
 | 
			
		||||
        VMSTATE_UINT64_V(vm_hsave, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT64_V(vm_vmcb, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT64_V(tsc_offset, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT64_V(intercept, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(intercept_cr_read, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(intercept_cr_write, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(intercept_dr_read, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(intercept_dr_write, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT32_V(intercept_exceptions, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT8_V(v_tpr, CPUX86State, 5),
 | 
			
		||||
        VMSTATE_UINT32_TEST(parent_obj.halted, X86CPU, version_is_5),
 | 
			
		||||
        VMSTATE_UINT64_V(env.vm_hsave, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT64_V(env.vm_vmcb, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT64_V(env.tsc_offset, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT64_V(env.intercept, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(env.intercept_cr_read, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(env.intercept_cr_write, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(env.intercept_dr_read, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT16_V(env.intercept_dr_write, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT32_V(env.intercept_exceptions, X86CPU, 5),
 | 
			
		||||
        VMSTATE_UINT8_V(env.v_tpr, X86CPU, 5),
 | 
			
		||||
        /* MTRRs */
 | 
			
		||||
        VMSTATE_UINT64_ARRAY_V(mtrr_fixed, CPUX86State, 11, 8),
 | 
			
		||||
        VMSTATE_UINT64_V(mtrr_deftype, CPUX86State, 8),
 | 
			
		||||
        VMSTATE_MTRR_VARS(mtrr_var, CPUX86State, 8, 8),
 | 
			
		||||
        VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8),
 | 
			
		||||
        VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8),
 | 
			
		||||
        VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, 8, 8),
 | 
			
		||||
        /* KVM-related states */
 | 
			
		||||
        VMSTATE_INT32_V(interrupt_injected, CPUX86State, 9),
 | 
			
		||||
        VMSTATE_UINT32_V(mp_state, CPUX86State, 9),
 | 
			
		||||
        VMSTATE_UINT64_V(tsc, CPUX86State, 9),
 | 
			
		||||
        VMSTATE_INT32_V(exception_injected, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(soft_interrupt, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(nmi_injected, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(nmi_pending, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(has_error_code, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT32_V(sipi_vector, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9),
 | 
			
		||||
        VMSTATE_UINT32_V(env.mp_state, X86CPU, 9),
 | 
			
		||||
        VMSTATE_UINT64_V(env.tsc, X86CPU, 9),
 | 
			
		||||
        VMSTATE_INT32_V(env.exception_injected, X86CPU, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(env.soft_interrupt, X86CPU, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(env.nmi_injected, X86CPU, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(env.nmi_pending, X86CPU, 11),
 | 
			
		||||
        VMSTATE_UINT8_V(env.has_error_code, X86CPU, 11),
 | 
			
		||||
        VMSTATE_UINT32_V(env.sipi_vector, X86CPU, 11),
 | 
			
		||||
        /* MCE */
 | 
			
		||||
        VMSTATE_UINT64_V(mcg_cap, CPUX86State, 10),
 | 
			
		||||
        VMSTATE_UINT64_V(mcg_status, CPUX86State, 10),
 | 
			
		||||
        VMSTATE_UINT64_V(mcg_ctl, CPUX86State, 10),
 | 
			
		||||
        VMSTATE_UINT64_ARRAY_V(mce_banks, CPUX86State, MCE_BANKS_DEF *4, 10),
 | 
			
		||||
        VMSTATE_UINT64_V(env.mcg_cap, X86CPU, 10),
 | 
			
		||||
        VMSTATE_UINT64_V(env.mcg_status, X86CPU, 10),
 | 
			
		||||
        VMSTATE_UINT64_V(env.mcg_ctl, X86CPU, 10),
 | 
			
		||||
        VMSTATE_UINT64_ARRAY_V(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4, 10),
 | 
			
		||||
        /* rdtscp */
 | 
			
		||||
        VMSTATE_UINT64_V(tsc_aux, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT64_V(env.tsc_aux, X86CPU, 11),
 | 
			
		||||
        /* KVM pvclock msr */
 | 
			
		||||
        VMSTATE_UINT64_V(system_time_msr, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT64_V(wall_clock_msr, CPUX86State, 11),
 | 
			
		||||
        VMSTATE_UINT64_V(env.system_time_msr, X86CPU, 11),
 | 
			
		||||
        VMSTATE_UINT64_V(env.wall_clock_msr, X86CPU, 11),
 | 
			
		||||
        /* XSAVE related fields */
 | 
			
		||||
        VMSTATE_UINT64_V(xcr0, CPUX86State, 12),
 | 
			
		||||
        VMSTATE_UINT64_V(xstate_bv, CPUX86State, 12),
 | 
			
		||||
        VMSTATE_YMMH_REGS_VARS(ymmh_regs, CPUX86State, CPU_NB_REGS, 12),
 | 
			
		||||
        VMSTATE_UINT64_V(env.xcr0, X86CPU, 12),
 | 
			
		||||
        VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12),
 | 
			
		||||
        VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, CPU_NB_REGS, 12),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
        /* The above list is not sorted /wrt version numbers, watch out! */
 | 
			
		||||
    },
 | 
			
		||||
@ -510,13 +519,3 @@ static const VMStateDescription vmstate_cpu = {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void cpu_save(QEMUFile *f, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    vmstate_save_state(f, &vmstate_cpu, opaque);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cpu_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		||||
{
 | 
			
		||||
    return vmstate_load_state(f, &vmstate_cpu, opaque, version_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -553,20 +553,25 @@ void helper_rdmsr(CPUX86State *env)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void do_hlt(CPUX86State *env)
 | 
			
		||||
static void do_hlt(X86CPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
    env->exception_index = EXCP_HLT;
 | 
			
		||||
    cpu_loop_exit(env);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void helper_hlt(CPUX86State *env, int next_eip_addend)
 | 
			
		||||
{
 | 
			
		||||
    X86CPU *cpu = x86_env_get_cpu(env);
 | 
			
		||||
 | 
			
		||||
    cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0);
 | 
			
		||||
    EIP += next_eip_addend;
 | 
			
		||||
 | 
			
		||||
    do_hlt(env);
 | 
			
		||||
    do_hlt(cpu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void helper_monitor(CPUX86State *env, target_ulong ptr)
 | 
			
		||||
@ -580,7 +585,8 @@ void helper_monitor(CPUX86State *env, target_ulong ptr)
 | 
			
		||||
 | 
			
		||||
void helper_mwait(CPUX86State *env, int next_eip_addend)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cpu;
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
    X86CPU *cpu;
 | 
			
		||||
 | 
			
		||||
    if ((uint32_t)ECX != 0) {
 | 
			
		||||
        raise_exception(env, EXCP0D_GPF);
 | 
			
		||||
@ -588,13 +594,14 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
 | 
			
		||||
    cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0);
 | 
			
		||||
    EIP += next_eip_addend;
 | 
			
		||||
 | 
			
		||||
    cpu = CPU(x86_env_get_cpu(env));
 | 
			
		||||
    cpu = x86_env_get_cpu(env);
 | 
			
		||||
    cs = CPU(cpu);
 | 
			
		||||
    /* XXX: not complete but not completely erroneous */
 | 
			
		||||
    if (cpu->cpu_index != 0 || env->next_cpu != NULL) {
 | 
			
		||||
    if (cs->cpu_index != 0 || env->next_cpu != NULL) {
 | 
			
		||||
        /* more than one CPU: do not sleep because another CPU may
 | 
			
		||||
           wake this one */
 | 
			
		||||
    } else {
 | 
			
		||||
        do_hlt(env);
 | 
			
		||||
        do_hlt(cpu);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1231,8 +1231,11 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUX86State *env)
 | 
			
		||||
void x86_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    X86CPU *cpu = X86_CPU(cs);
 | 
			
		||||
    CPUX86State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
    /* if user mode only, we simulate a fake exception
 | 
			
		||||
       which will be handled outside the cpu execution
 | 
			
		||||
 | 
			
		||||
@ -271,7 +271,9 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 | 
			
		||||
    env->hflags2 |= HF2_GIF_MASK;
 | 
			
		||||
 | 
			
		||||
    if (int_ctl & V_IRQ_MASK) {
 | 
			
		||||
        env->interrupt_request |= CPU_INTERRUPT_VIRQ;
 | 
			
		||||
        CPUState *cs = CPU(x86_env_get_cpu(env));
 | 
			
		||||
 | 
			
		||||
        cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* maybe we need to inject an event */
 | 
			
		||||
@ -548,6 +550,7 @@ void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
 | 
			
		||||
/* Note: currently only 32 bits of exit_code are used */
 | 
			
		||||
void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(x86_env_get_cpu(env));
 | 
			
		||||
    uint32_t int_ctl;
 | 
			
		||||
 | 
			
		||||
    qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
 | 
			
		||||
@ -594,7 +597,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
 | 
			
		||||
    int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
 | 
			
		||||
    int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
 | 
			
		||||
    int_ctl |= env->v_tpr & V_TPR_MASK;
 | 
			
		||||
    if (env->interrupt_request & CPU_INTERRUPT_VIRQ) {
 | 
			
		||||
    if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
 | 
			
		||||
        int_ctl |= V_IRQ_MASK;
 | 
			
		||||
    }
 | 
			
		||||
    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);
 | 
			
		||||
@ -615,7 +618,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
 | 
			
		||||
    env->hflags &= ~HF_SVMI_MASK;
 | 
			
		||||
    env->intercept = 0;
 | 
			
		||||
    env->intercept_exceptions = 0;
 | 
			
		||||
    env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
 | 
			
		||||
    cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
 | 
			
		||||
    env->tsc_offset = 0;
 | 
			
		||||
 | 
			
		||||
    env->gdt.base  = ldq_phys(env->vm_hsave + offsetof(struct vmcb,
 | 
			
		||||
 | 
			
		||||
@ -71,4 +71,10 @@ static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
 | 
			
		||||
 | 
			
		||||
#define ENV_OFFSET offsetof(LM32CPU, env)
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
extern const struct VMStateDescription vmstate_lm32_cpu;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void lm32_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -83,6 +83,9 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
 | 
			
		||||
    lcc->parent_reset = cc->reset;
 | 
			
		||||
    cc->reset = lm32_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->do_interrupt = lm32_cpu_do_interrupt;
 | 
			
		||||
    cpu_class_set_vmsd(cc, &vmstate_lm32_cpu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo lm32_cpu_type_info = {
 | 
			
		||||
 | 
			
		||||
@ -189,7 +189,6 @@ struct CPULM32State {
 | 
			
		||||
LM32CPU *cpu_lm32_init(const char *cpu_model);
 | 
			
		||||
void cpu_lm32_list(FILE *f, fprintf_function cpu_fprintf);
 | 
			
		||||
int cpu_lm32_exec(CPULM32State *s);
 | 
			
		||||
void do_interrupt(CPULM32State *env);
 | 
			
		||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
 | 
			
		||||
   signal handlers to inform the virtual CPU of exceptions. non zero
 | 
			
		||||
   is returned if the signal was handled by the virtual CPU.  */
 | 
			
		||||
@ -212,8 +211,6 @@ static inline CPULM32State *cpu_init(const char *cpu_model)
 | 
			
		||||
#define cpu_gen_code cpu_lm32_gen_code
 | 
			
		||||
#define cpu_signal_handler cpu_lm32_signal_handler
 | 
			
		||||
 | 
			
		||||
#define CPU_SAVE_VERSION 1
 | 
			
		||||
 | 
			
		||||
int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
 | 
			
		||||
                              int mmu_idx);
 | 
			
		||||
#define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault
 | 
			
		||||
@ -254,9 +251,7 @@ static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPULM32State *env = &LM32_CPU(cpu)->env;
 | 
			
		||||
 | 
			
		||||
    return env->interrupt_request & CPU_INTERRUPT_HARD;
 | 
			
		||||
    return cpu->interrupt_request & CPU_INTERRUPT_HARD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "exec/exec-all.h"
 | 
			
		||||
 | 
			
		||||
@ -42,8 +42,11 @@ hwaddr cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr)
 | 
			
		||||
    return addr & TARGET_PAGE_MASK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPULM32State *env)
 | 
			
		||||
void lm32_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    LM32CPU *cpu = LM32_CPU(cs);
 | 
			
		||||
    CPULM32State *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    qemu_log_mask(CPU_LOG_INT,
 | 
			
		||||
            "exception at pc=%x type=%x\n", env->pc, env->exception_index);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
#include "hw/hw.h"
 | 
			
		||||
#include "hw/boards.h"
 | 
			
		||||
 | 
			
		||||
static const VMStateDescription vmstate_cpu = {
 | 
			
		||||
    .name = "cpu",
 | 
			
		||||
    .version_id = CPU_SAVE_VERSION,
 | 
			
		||||
static const VMStateDescription vmstate_env = {
 | 
			
		||||
    .name = "env",
 | 
			
		||||
    .version_id = 1,
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField[]) {
 | 
			
		||||
@ -22,12 +22,13 @@ static const VMStateDescription vmstate_cpu = {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void cpu_save(QEMUFile *f, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    vmstate_save_state(f, &vmstate_cpu, opaque);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cpu_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		||||
{
 | 
			
		||||
    return vmstate_load_state(f, &vmstate_cpu, opaque, version_id);
 | 
			
		||||
}
 | 
			
		||||
const VMStateDescription vmstate_lm32_cpu = {
 | 
			
		||||
    .name = "cpu",
 | 
			
		||||
    .version_id = 1,
 | 
			
		||||
    .minimum_version_id = 1,
 | 
			
		||||
    .minimum_version_id_old = 1,
 | 
			
		||||
    .fields      = (VMStateField[]) {
 | 
			
		||||
        VMSTATE_STRUCT(env, LM32CPU, 1, vmstate_env, CPULM32State),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,9 @@ void helper_raise_exception(CPULM32State *env, uint32_t index)
 | 
			
		||||
 | 
			
		||||
void helper_hlt(CPULM32State *env)
 | 
			
		||||
{
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    CPUState *cs = CPU(lm32_env_get_cpu(env));
 | 
			
		||||
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
    env->exception_index = EXCP_HLT;
 | 
			
		||||
    cpu_loop_exit(env);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -70,4 +70,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
 | 
			
		||||
 | 
			
		||||
#define ENV_OFFSET offsetof(M68kCPU, env)
 | 
			
		||||
 | 
			
		||||
void m68k_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -186,6 +186,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 | 
			
		||||
    cc->reset = m68k_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->class_by_name = m68k_cpu_class_by_name;
 | 
			
		||||
    cc->do_interrupt = m68k_cpu_do_interrupt;
 | 
			
		||||
    dc->vmsd = &vmstate_m68k_cpu;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -119,7 +119,6 @@ void m68k_tcg_init(void);
 | 
			
		||||
void m68k_cpu_init_gdb(M68kCPU *cpu);
 | 
			
		||||
M68kCPU *cpu_m68k_init(const char *cpu_model);
 | 
			
		||||
int cpu_m68k_exec(CPUM68KState *s);
 | 
			
		||||
void do_interrupt(CPUM68KState *env1);
 | 
			
		||||
void do_interrupt_m68k_hardirq(CPUM68KState *env1);
 | 
			
		||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
 | 
			
		||||
   signal handlers to inform the virtual CPU of exceptions. non zero
 | 
			
		||||
@ -265,9 +264,7 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUM68KState *env = &M68K_CPU(cpu)->env;
 | 
			
		||||
 | 
			
		||||
    return env->interrupt_request & CPU_INTERRUPT_HARD;
 | 
			
		||||
    return cpu->interrupt_request & CPU_INTERRUPT_HARD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "exec/exec-all.h"
 | 
			
		||||
 | 
			
		||||
@ -312,14 +312,16 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
 | 
			
		||||
   simplicitly we calculate it when the interrupt is signalled.  */
 | 
			
		||||
void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    CPUM68KState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->pending_level = level;
 | 
			
		||||
    env->pending_vector = vector;
 | 
			
		||||
    if (level)
 | 
			
		||||
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
    else
 | 
			
		||||
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 | 
			
		||||
    if (level) {
 | 
			
		||||
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,11 @@
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUM68KState *env)
 | 
			
		||||
void m68k_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    M68kCPU *cpu = M68K_CPU(cs);
 | 
			
		||||
    CPUM68KState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->exception_index = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -84,6 +87,7 @@ static void do_rte(CPUM68KState *env)
 | 
			
		||||
 | 
			
		||||
static void do_interrupt_all(CPUM68KState *env, int is_hw)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs;
 | 
			
		||||
    uint32_t sp;
 | 
			
		||||
    uint32_t fmt;
 | 
			
		||||
    uint32_t retaddr;
 | 
			
		||||
@ -108,7 +112,8 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
 | 
			
		||||
                do_m68k_semihosting(env, env->dregs[0]);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            env->halted = 1;
 | 
			
		||||
            cs = CPU(m68k_env_get_cpu(env));
 | 
			
		||||
            cs->halted = 1;
 | 
			
		||||
            env->exception_index = EXCP_HLT;
 | 
			
		||||
            cpu_loop_exit(env);
 | 
			
		||||
            return;
 | 
			
		||||
@ -147,8 +152,11 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
 | 
			
		||||
    env->pc = cpu_ldl_kernel(env, env->vbr + vector);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUM68KState *env)
 | 
			
		||||
void m68k_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    M68kCPU *cpu = M68K_CPU(cs);
 | 
			
		||||
    CPUM68KState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    do_interrupt_all(env, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,5 @@ DEFO32(CC_X, cc_x)
 | 
			
		||||
DEFO32(DIV1, div1)
 | 
			
		||||
DEFO32(DIV2, div2)
 | 
			
		||||
DEFO32(EXCEPTION, exception_index)
 | 
			
		||||
DEFO32(HALTED, halted)
 | 
			
		||||
DEFO32(MACSR, macsr)
 | 
			
		||||
DEFO32(MAC_MASK, mac_mask)
 | 
			
		||||
 | 
			
		||||
@ -42,6 +42,8 @@
 | 
			
		||||
#undef DEFO64
 | 
			
		||||
#undef DEFF64
 | 
			
		||||
 | 
			
		||||
static TCGv_i32 cpu_halted;
 | 
			
		||||
 | 
			
		||||
static TCGv_ptr cpu_env;
 | 
			
		||||
 | 
			
		||||
static char cpu_reg_names[3*8*3 + 5*4];
 | 
			
		||||
@ -76,6 +78,10 @@ void m68k_tcg_init(void)
 | 
			
		||||
#undef DEFO64
 | 
			
		||||
#undef DEFF64
 | 
			
		||||
 | 
			
		||||
    cpu_halted = tcg_global_mem_new_i32(TCG_AREG0,
 | 
			
		||||
                                        -offsetof(M68kCPU, env) +
 | 
			
		||||
                                        offsetof(CPUState, halted), "HALTED");
 | 
			
		||||
 | 
			
		||||
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 | 
			
		||||
 | 
			
		||||
    p = cpu_reg_names;
 | 
			
		||||
@ -2024,7 +2030,7 @@ DISAS_INSN(stop)
 | 
			
		||||
    s->pc += 2;
 | 
			
		||||
 | 
			
		||||
    gen_set_sr_im(s, ext, 0);
 | 
			
		||||
    tcg_gen_movi_i32(QREG_HALTED, 1);
 | 
			
		||||
    tcg_gen_movi_i32(cpu_halted, 1);
 | 
			
		||||
    gen_exception(s, s->pc, EXCP_HLT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -70,4 +70,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
 | 
			
		||||
 | 
			
		||||
#define ENV_OFFSET offsetof(MicroBlazeCPU, env)
 | 
			
		||||
 | 
			
		||||
void mb_cpu_do_interrupt(CPUState *cs);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -131,6 +131,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
    mcc->parent_reset = cc->reset;
 | 
			
		||||
    cc->reset = mb_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->do_interrupt = mb_cpu_do_interrupt;
 | 
			
		||||
    dc->vmsd = &vmstate_mb_cpu;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -275,7 +275,6 @@ struct CPUMBState {
 | 
			
		||||
void mb_tcg_init(void);
 | 
			
		||||
MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 | 
			
		||||
int cpu_mb_exec(CPUMBState *s);
 | 
			
		||||
void do_interrupt(CPUMBState *env);
 | 
			
		||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
 | 
			
		||||
   signal handlers to inform the virtual CPU of exceptions. non zero
 | 
			
		||||
   is returned if the signal was handled by the virtual CPU.  */
 | 
			
		||||
@ -374,9 +373,7 @@ void cpu_unassigned_access(CPUMBState *env1, hwaddr addr,
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUMBState *env = &MICROBLAZE_CPU(cpu)->env;
 | 
			
		||||
 | 
			
		||||
    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 | 
			
		||||
    return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "exec/exec-all.h"
 | 
			
		||||
 | 
			
		||||
@ -26,8 +26,11 @@
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
void do_interrupt (CPUMBState *env)
 | 
			
		||||
void mb_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
 | 
			
		||||
    CPUMBState *env = &cpu->env;
 | 
			
		||||
 | 
			
		||||
    env->exception_index = -1;
 | 
			
		||||
    env->res_addr = RES_ADDR_NONE;
 | 
			
		||||
    env->regs[14] = env->sregs[SR_PC];
 | 
			
		||||
@ -109,8 +112,10 @@ int cpu_mb_handle_mmu_fault (CPUMBState *env, target_ulong address, int rw,
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUMBState *env)
 | 
			
		||||
void mb_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
 | 
			
		||||
    CPUMBState *env = &cpu->env;
 | 
			
		||||
    uint32_t t;
 | 
			
		||||
 | 
			
		||||
    /* IMM flag cannot propagate across a branch and into the dslot.  */
 | 
			
		||||
 | 
			
		||||
@ -74,4 +74,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
 | 
			
		||||
 | 
			
		||||
#define ENV_OFFSET offsetof(MIPSCPU, env)
 | 
			
		||||
 | 
			
		||||
void mips_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -78,6 +78,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 | 
			
		||||
 | 
			
		||||
    mcc->parent_reset = cc->reset;
 | 
			
		||||
    cc->reset = mips_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->do_interrupt = mips_cpu_do_interrupt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo mips_cpu_type_info = {
 | 
			
		||||
 | 
			
		||||
@ -663,7 +663,6 @@ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
 | 
			
		||||
int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
 | 
			
		||||
                               int mmu_idx);
 | 
			
		||||
#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
 | 
			
		||||
void do_interrupt (CPUMIPSState *env);
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
 | 
			
		||||
hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
 | 
			
		||||
@ -722,7 +721,7 @@ static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
    /* It is implementation dependent if non-enabled interrupts
 | 
			
		||||
       wake-up the CPU, however most of the implementations only
 | 
			
		||||
       check for interrupts that can be taken. */
 | 
			
		||||
    if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
    if ((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
 | 
			
		||||
        cpu_mips_hw_interrupts_pending(env)) {
 | 
			
		||||
        has_work = true;
 | 
			
		||||
    }
 | 
			
		||||
@ -731,7 +730,7 @@ static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
 | 
			
		||||
        /* The QEMU model will issue an _WAKE request whenever the CPUs
 | 
			
		||||
           should be woken up.  */
 | 
			
		||||
        if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
 | 
			
		||||
        if (cpu->interrupt_request & CPU_INTERRUPT_WAKE) {
 | 
			
		||||
            has_work = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -396,10 +396,11 @@ static void set_hflags_for_handler (CPUMIPSState *env)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void do_interrupt (CPUMIPSState *env)
 | 
			
		||||
void mips_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    MIPSCPU *cpu = MIPS_CPU(cs);
 | 
			
		||||
    CPUMIPSState *env = &cpu->env;
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    MIPSCPU *cpu = mips_env_get_cpu(env);
 | 
			
		||||
    target_ulong offset;
 | 
			
		||||
    int cause = -1;
 | 
			
		||||
    const char *name;
 | 
			
		||||
 | 
			
		||||
@ -515,29 +515,30 @@ void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
 | 
			
		||||
/* SMP helpers.  */
 | 
			
		||||
static bool mips_vpe_is_wfi(MIPSCPU *c)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cpu = CPU(c);
 | 
			
		||||
    CPUMIPSState *env = &c->env;
 | 
			
		||||
 | 
			
		||||
    /* If the VPE is halted but otherwise active, it means it's waiting for
 | 
			
		||||
       an interrupt.  */
 | 
			
		||||
    return env->halted && mips_vpe_active(env);
 | 
			
		||||
    return cpu->halted && mips_vpe_active(env);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void mips_vpe_wake(CPUMIPSState *c)
 | 
			
		||||
static inline void mips_vpe_wake(MIPSCPU *c)
 | 
			
		||||
{
 | 
			
		||||
    /* Dont set ->halted = 0 directly, let it be done via cpu_has_work
 | 
			
		||||
       because there might be other conditions that state that c should
 | 
			
		||||
       be sleeping.  */
 | 
			
		||||
    cpu_interrupt(c, CPU_INTERRUPT_WAKE);
 | 
			
		||||
    cpu_interrupt(CPU(c), CPU_INTERRUPT_WAKE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void mips_vpe_sleep(MIPSCPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUMIPSState *c = &cpu->env;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    /* The VPE was shut off, really go to bed.
 | 
			
		||||
       Reset any old _WAKE requests.  */
 | 
			
		||||
    c->halted = 1;
 | 
			
		||||
    cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE);
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
    cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void mips_tc_wake(MIPSCPU *cpu, int tc)
 | 
			
		||||
@ -546,7 +547,7 @@ static inline void mips_tc_wake(MIPSCPU *cpu, int tc)
 | 
			
		||||
 | 
			
		||||
    /* FIXME: TC reschedule.  */
 | 
			
		||||
    if (mips_vpe_active(c) && !mips_vpe_is_wfi(cpu)) {
 | 
			
		||||
        mips_vpe_wake(c);
 | 
			
		||||
        mips_vpe_wake(cpu);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1724,7 +1725,7 @@ target_ulong helper_evpe(CPUMIPSState *env)
 | 
			
		||||
            && !mips_vpe_is_wfi(other_cpu)) {
 | 
			
		||||
            /* Enable the VPE.  */
 | 
			
		||||
            other_cpu_env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
 | 
			
		||||
            mips_vpe_wake(other_cpu_env); /* And wake it up.  */
 | 
			
		||||
            mips_vpe_wake(other_cpu); /* And wake it up.  */
 | 
			
		||||
        }
 | 
			
		||||
        other_cpu_env = other_cpu_env->next_cpu;
 | 
			
		||||
    } while (other_cpu_env);
 | 
			
		||||
@ -2099,8 +2100,10 @@ void helper_pmon(CPUMIPSState *env, int function)
 | 
			
		||||
 | 
			
		||||
void helper_wait(CPUMIPSState *env)
 | 
			
		||||
{
 | 
			
		||||
    env->halted = 1;
 | 
			
		||||
    cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE);
 | 
			
		||||
    CPUState *cs = CPU(mips_env_get_cpu(env));
 | 
			
		||||
 | 
			
		||||
    cs->halted = 1;
 | 
			
		||||
    cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
 | 
			
		||||
    helper_raise_exception(env, EXCP_HLT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16004,7 +16004,7 @@ void cpu_state_reset(CPUMIPSState *env)
 | 
			
		||||
            env->tcs[i].CP0_TCHalt = 1;
 | 
			
		||||
        }
 | 
			
		||||
        env->active_tc.CP0_TCHalt = 1;
 | 
			
		||||
        env->halted = 1;
 | 
			
		||||
        cs->halted = 1;
 | 
			
		||||
 | 
			
		||||
        if (cs->cpu_index == 0) {
 | 
			
		||||
            /* VPE0 starts up enabled.  */
 | 
			
		||||
@ -16012,7 +16012,7 @@ void cpu_state_reset(CPUMIPSState *env)
 | 
			
		||||
            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
 | 
			
		||||
 | 
			
		||||
            /* TC0 starts up unhalted.  */
 | 
			
		||||
            env->halted = 0;
 | 
			
		||||
            cs->halted = 0;
 | 
			
		||||
            env->active_tc.CP0_TCHalt = 0;
 | 
			
		||||
            env->tcs[0].CP0_TCHalt = 0;
 | 
			
		||||
            /* With thread 0 active.  */
 | 
			
		||||
 | 
			
		||||
@ -148,6 +148,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
    cc->reset = openrisc_cpu_reset;
 | 
			
		||||
 | 
			
		||||
    cc->class_by_name = openrisc_cpu_class_by_name;
 | 
			
		||||
    cc->do_interrupt = openrisc_cpu_do_interrupt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_register(const OpenRISCCPUInfo *info)
 | 
			
		||||
 | 
			
		||||
@ -346,7 +346,7 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
 | 
			
		||||
 | 
			
		||||
void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
 | 
			
		||||
int cpu_openrisc_exec(CPUOpenRISCState *s);
 | 
			
		||||
void do_interrupt(CPUOpenRISCState *env);
 | 
			
		||||
void openrisc_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
void openrisc_translate_init(void);
 | 
			
		||||
int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
 | 
			
		||||
                                  target_ulong address,
 | 
			
		||||
@ -423,9 +423,7 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env)
 | 
			
		||||
#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUOpenRISCState *env = &OPENRISC_CPU(cpu)->env;
 | 
			
		||||
 | 
			
		||||
    return env->interrupt_request & (CPU_INTERRUPT_HARD |
 | 
			
		||||
    return cpu->interrupt_request & (CPU_INTERRUPT_HARD |
 | 
			
		||||
                                     CPU_INTERRUPT_TIMER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,10 @@
 | 
			
		||||
#include "hw/loader.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUOpenRISCState *env)
 | 
			
		||||
void openrisc_cpu_do_interrupt(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
 | 
			
		||||
    CPUOpenRISCState *env = &cpu->env;
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
    if (env->flags & D_FLAG) { /* Delay Slot insn */
 | 
			
		||||
        env->flags &= ~D_FLAG;
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@
 | 
			
		||||
void HELPER(rfe)(CPUOpenRISCState *env)
 | 
			
		||||
{
 | 
			
		||||
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
    int need_flush_tlb = (cpu->env.sr & (SR_SM | SR_IME | SR_DME)) ^
 | 
			
		||||
                         (cpu->env.esr & (SR_SM | SR_IME | SR_DME));
 | 
			
		||||
@ -53,5 +54,5 @@ void HELPER(rfe)(CPUOpenRISCState *env)
 | 
			
		||||
        tlb_flush(&cpu->env, 1);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    cpu->env.interrupt_request |= CPU_INTERRUPT_EXITTB;
 | 
			
		||||
    cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
 | 
			
		||||
    int idx;
 | 
			
		||||
 | 
			
		||||
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    switch (spr) {
 | 
			
		||||
    case TO_SPR(0, 0): /* VR */
 | 
			
		||||
@ -132,7 +133,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
 | 
			
		||||
                env->ttmr = (rb & ~TTMR_IP) + ip;
 | 
			
		||||
            } else {    /* Clear IP bit.  */
 | 
			
		||||
                env->ttmr = rb & ~TTMR_IP;
 | 
			
		||||
                env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
 | 
			
		||||
                cs->interrupt_request &= ~CPU_INTERRUPT_TIMER;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            cpu_openrisc_count_update(cpu);
 | 
			
		||||
 | 
			
		||||
@ -95,4 +95,6 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
 | 
			
		||||
 | 
			
		||||
PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
 | 
			
		||||
 | 
			
		||||
void ppc_cpu_do_interrupt(CPUState *cpu);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -1133,7 +1133,6 @@ int cpu_ppc_signal_handler (int host_signum, void *pinfo,
 | 
			
		||||
int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
 | 
			
		||||
                              int mmu_idx);
 | 
			
		||||
#define cpu_handle_mmu_fault cpu_ppc_handle_mmu_fault
 | 
			
		||||
void do_interrupt (CPUPPCState *env);
 | 
			
		||||
void ppc_hw_interrupt (CPUPPCState *env);
 | 
			
		||||
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
@ -2217,9 +2216,10 @@ extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
 | 
			
		||||
 | 
			
		||||
static inline bool cpu_has_work(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    CPUPPCState *env = &POWERPC_CPU(cpu)->env;
 | 
			
		||||
    PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
 | 
			
		||||
    CPUPPCState *env = &ppc_cpu->env;
 | 
			
		||||
 | 
			
		||||
    return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
 | 
			
		||||
    return msr_ee && (cpu->interrupt_request & CPU_INTERRUPT_HARD);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "exec/exec-all.h"
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user