diff options
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/cpu.h | 9 | ||||
-rw-r--r-- | target-s390x/helper.c | 15 |
2 files changed, 21 insertions, 3 deletions
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index a66aa01..202c098 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -315,6 +315,15 @@ unsigned s390_del_running_cpu(CPUState *env); /* from s390-virtio-bus */ extern const target_phys_addr_t virtio_size; +#else +static inline void s390_add_running_cpu(CPUState *env) +{ +} + +static inline unsigned s390_del_running_cpu(CPUState *env) +{ + return 0; +} #endif void cpu_lock(void); void cpu_unlock(void); diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 4145104..10cc9dd 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -26,6 +26,9 @@ #include "gdbstub.h" #include "qemu-common.h" #include "qemu-timer.h" +#ifndef CONFIG_USER_ONLY +#include "sysemu.h" +#endif //#define DEBUG_S390 //#define DEBUG_S390_PTE @@ -131,6 +134,7 @@ void cpu_reset(CPUS390XState *env) memset(env, 0, offsetof(CPUS390XState, breakpoints)); /* FIXME: reset vector? */ tlb_flush(env, 1); + s390_add_running_cpu(env); } #ifndef CONFIG_USER_ONLY @@ -466,11 +470,15 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong vaddr) void load_psw(CPUState *env, uint64_t mask, uint64_t addr) { if (mask & PSW_MASK_WAIT) { - env->halted = 1; - env->exception_index = EXCP_HLT; if (!(mask & (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK))) { - /* XXX disabled wait state - CPU is dead */ + if (s390_del_running_cpu(env) == 0) { +#ifndef CONFIG_USER_ONLY + qemu_system_shutdown_request(); +#endif + } } + env->halted = 1; + env->exception_index = EXCP_HLT; } env->psw.addr = addr; @@ -599,6 +607,7 @@ void do_interrupt (CPUState *env) qemu_log("%s: %d at pc=%" PRIx64 "\n", __FUNCTION__, env->exception_index, env->psw.addr); + s390_add_running_cpu(env); /* handle external interrupts */ if ((env->psw.mask & PSW_MASK_EXT) && env->exception_index == -1) { |