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:
Anthony Liguori 2013-03-14 14:50:58 -05:00
commit 3d34a4110c
133 changed files with 1240 additions and 850 deletions

View File

@ -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
View File

@ -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
View File

@ -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;

View File

@ -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);
}

View File

@ -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,

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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,

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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];
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */ \

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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)
{

View File

@ -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,

View File

@ -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

View File

@ -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 = {

View File

@ -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);

View File

@ -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)) {

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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.

View File

@ -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);
}

View File

@ -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

View File

@ -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 = {

View File

@ -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"

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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 = {

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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 = {

View File

@ -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"

View File

@ -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);

View File

@ -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()
}
};

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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"

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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"

View File

@ -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. */

View File

@ -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

View File

@ -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 = {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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. */

View File

@ -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)

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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