Commit 3d34a411 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

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
parents 0ec4a8e6 0ad6773f
Loading
Loading
Loading
Loading
+38 −32
Original line number Diff line number Diff line
@@ -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;
+6 −11
Original line number Diff line number Diff line
@@ -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);
        }
+16 −14
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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);
            }
+9 −9
Original line number Diff line number Diff line
@@ -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,
Loading