How to cleanly exit QEMU after executing bare metal program without user intervention?
I recommend to use Angel interface for ARM processores. It is very helpful for debugging. You can read something about it on ARM Info Center. Especially look at operation angel_SWIreason_ReportException (0x18) and parameter ADP_Stopped_ApplicationExit to which QEMU will understand that your application has ended.
Don't forget to run QEMU with -semihosting argument, like this:
qemu-system-arm -nographic -semihosting -kernel your_binary
Here is the code to tell QEMU to stop (you have to use some assembler):
register int reg0 asm("r0");
register int reg1 asm("r1");
reg0 = 0x18; // angel_SWIreason_ReportException
reg1 = 0x20026; // ADP_Stopped_ApplicationExit
asm("svc 0x00123456"); // make semihosting call
You can also look at my project at github where I used it.
Typically you need to do whatever on the hardware would cause a system shutdown (power off); QEMU will make that do an 'exit QEMU'. Unfortunately not all of the hardware we emulate implements a power-off mechanism (and sometimes it's not wired up in the QEMU model, though that's generally an easy bug to fix).