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