sim: Make the drain handler return unexpected exit events

The simulator can currently lose exit events while draining, which
confuses both simulation scripts and the simulated system. This
changeset modifies m5.drain() to return a tuple (drain_ok,
exit_event). The exit_event is valid if drain_ok is False and the
simulation script is expected to call drain() again if it still needs
the system to be drained.

In order to keep old configuration scripts from breaking, a separate
function, m5.legacyDrain(), is introduced with the same semantics as
the old drain function. Unlike the old function, this one emits a
warning if an unexpected simulation event occurs. Both m5.checkpoint()
and m5.switchCpus() have been updated to use this function instead of
drain(). Configuration scripts that need reliable draining should call
drain() manually and then request a checkpoint/CPU switch with the
keyword argument do_drain=False.