Skip to content

Commit

Permalink
cpu: Move halted and interrupt_request fields to CPUState
Browse files Browse the repository at this point in the history
Both fields are used in VMState, thus need to be moved together.
Explicitly zero them on reset since they were located before
breakpoints.

Pass PowerPCCPU to kvmppc_handle_halt().

Signed-off-by: Andreas Färber <afaerber@suse.de>
  • Loading branch information
afaerber committed Mar 12, 2013
1 parent 21317bc commit 259186a
Show file tree
Hide file tree
Showing 70 changed files with 319 additions and 224 deletions.
34 changes: 18 additions & 16 deletions cpu-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,12 @@ int cpu_exec(CPUArchState *env)
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;
Expand Down Expand Up @@ -278,31 +278,31 @@ 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);
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
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);
}
#endif
#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
Expand All @@ -319,17 +319,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) &&
Expand All @@ -341,7 +341,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);
Expand All @@ -359,7 +360,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
}
Expand All @@ -370,8 +371,9 @@ 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)
Expand Down Expand Up @@ -548,8 +550,8 @@ int cpu_exec(CPUArchState *env)
#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;
Expand Down
4 changes: 2 additions & 2 deletions cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
16 changes: 9 additions & 7 deletions exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,12 @@ void cpu_exec_init_all(void)

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;
}
Expand All @@ -240,8 +240,8 @@ 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()
}
};
Expand Down Expand Up @@ -293,7 +293,7 @@ void cpu_exec_init(CPUArchState *env)
#if defined(CONFIG_USER_ONLY)
cpu_list_unlock();
#endif
vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env);
vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
cpu_save, cpu_load, env);
Expand Down Expand Up @@ -494,7 +494,9 @@ void cpu_single_step(CPUArchState *env, int enabled)

void cpu_reset_interrupt(CPUArchState *env, int mask)
{
env->interrupt_request &= ~mask;
CPUState *cpu = ENV_GET_CPU(env);

cpu->interrupt_request &= ~mask;
}

void cpu_exit(CPUArchState *env)
Expand Down
2 changes: 1 addition & 1 deletion gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
7 changes: 5 additions & 2 deletions hw/arm/omap1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -3754,8 +3756,9 @@ 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) {
if (cpu->halted) {
cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB);
}
}
Expand Down
3 changes: 2 additions & 1 deletion hw/arm/pxa2xx_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -118,7 +119,7 @@ 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])) {
if (cpu->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) {
cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_EXITTB);
}
}
Expand Down
3 changes: 2 additions & 1 deletion hw/arm/pxa2xx_pic.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ 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]) {
Expand Down
6 changes: 3 additions & 3 deletions hw/i386/xen_machine_pv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion hw/openrisc/cputimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
10 changes: 6 additions & 4 deletions hw/ppc/e500.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 14 additions & 8 deletions hw/ppc/ppc.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,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 */
Expand All @@ -87,6 +87,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 */
Expand Down Expand Up @@ -126,7 +128,7 @@ 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:
Expand Down Expand Up @@ -174,6 +176,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 */
Expand Down Expand Up @@ -203,11 +207,11 @@ 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:
Expand Down Expand Up @@ -295,6 +299,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) {
Expand Down Expand Up @@ -332,11 +338,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:
Expand Down
2 changes: 1 addition & 1 deletion hw/ppc/ppce500_spin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 259186a

Please sign in to comment.