Hi Peter and Leon, With a bit of thinking, I agree, that the question of session termination on WAIT instruction is quite complicated in case of multi-core system, background i/o activity, mipsR6 core etc. So I'm going to find another solution for the task. What I essentially want here is to stop the simulator when the target Unix system is halted, like:
$ /usr/local/qemu-mips/bin/qemu-system-mipsel -M pic32mx7-max32 -nographic -monitor none -serial stdio -bios boot-max32.hex -kernel unix.hex -sd sdcard.img Board: chipKIT Max32 Processor: M4K RAM size: 128 kbytes Load file: 'boot-max32.hex', 6720 bytes Load file: 'unix.hex', 144992 bytes Card0 image 'sdcard.img', 102888 kbytes [...] 2.11 BSD UNIX (pic32) (console) login: root Password: Welcome to RetroBSD! erase, kill ^U, intr ^C # halt killing processes... done syncing disks... done halted $ _ <-- QEMU terminated On BSD, the halt command uses reboot(RB_HALT) system call to terminate the operating system. It essentially results in an endless loop on wait instruction with interrupts disabled., like "for(;;) { asm("wait"); }". For pic32 it makes little sense to continue simulation in this case. Fortunately, I've found a solution which does not require modification of generic code. Everything can be done in the platform-specific part. Thanks, --Serge 2015-06-30 11:08 GMT-07:00 Peter Crosthwaite <peter.crosthwa...@xilinx.com>: > On Tue, Jun 30, 2015 at 7:10 AM, Leon Alrae <leon.al...@imgtec.com> wrote: >> Hi Serge, >> >> On 30/06/2015 06:02, Serge Vakulenko wrote: >>> Signed-off-by: Serge Vakulenko <se...@vak.ru> >>> --- >>> target-mips/op_helper.c | 7 +++++++ >>> 1 file changed, 7 insertions(+) >>> >>> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c >>> index 2a9ddff..1b7caeb 100644 >>> --- a/target-mips/op_helper.c >>> +++ b/target-mips/op_helper.c >>> @@ -22,6 +22,7 @@ >>> #include "exec/helper-proto.h" >>> #include "exec/cpu_ldst.h" >>> #include "sysemu/kvm.h" >>> +#include "sysemu/sysemu.h" >>> >>> #ifndef CONFIG_USER_ONLY >>> static inline void cpu_mips_tlb_flush (CPUMIPSState *env, int >>> flush_global); >>> @@ -2235,6 +2236,12 @@ void helper_wait(CPUMIPSState *env) >>> { >>> CPUState *cs = CPU(mips_env_get_cpu(env)); >>> >>> +#ifndef CONFIG_USER_ONLY >>> + if (!(env->CP0_Status & (1 << CP0St_IE))) { >>> + /* WAIT instruction with interrupts disabled - halt the >>> simulation. */ >>> + qemu_system_shutdown_request(); >>> + } >>> +#endif >> >> Why do you want to stop the simulation, wouldn't it be beneficial to leave it >> running? For debugging for example, the user would be still able to inspect >> the state, that could help to find a clue why CPU got suspended forever. >> > > In theory, there may also be other actors in the system. Even if the > CPU is in a never-going-to-come-back-to-life state, other-things may > still be happening. This would be best as some sort of core feature to > detect total-inaction of the system. That is, there are no delayed > events pending (timed events and AIOs) and the CPUs are halted. Then > this would be a user option to stop the system on reaching the > machine-inactive state and it would be applicable beyond mips. > > Regards, > Peter > >> Also, if we take into account implementations (currently not supported in >> QEMU) where CPU can be woken up by a disabled interrupt (the Config7.WII bit >> in P5600 for example), then this won't be correct. >> >> Thanks, >> Leon >> >>