/* Generic simulator halt/restart.
   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
   Contributed by Cygnus Support.

This file is part of GDB, the GNU debugger.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include <stdio.h>

#include "sim-main.h"
#include "sim-assert.h"

/* Get the run state.
   REASON/SIGRC are the values returned by sim_stop_reason.
   ??? Should each cpu have its own copy?  */

void
sim_engine_get_run_state (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
{
  sim_engine *engine = STATE_ENGINE (sd);
  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  *reason = engine->reason;
  *sigrc = engine->sigrc;
}

/* Set the run state to REASON/SIGRC.
   REASON/SIGRC are the values returned by sim_stop_reason.
   ??? Should each cpu have its own copy?  */

void
sim_engine_set_run_state (SIM_DESC sd, enum sim_stop reason, int sigrc)
{
  sim_engine *engine = STATE_ENGINE (sd);
  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  engine->reason = reason;
  engine->sigrc = sigrc;
}

/* Generic halt */

void
sim_engine_halt (SIM_DESC sd,
		 sim_cpu *last_cpu,
		 sim_cpu *next_cpu, /* NULL - use default */
		 sim_cia cia,
		 enum sim_stop reason,
		 int sigrc)
{
  sim_engine *engine = STATE_ENGINE (sd);
  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  if (engine->jmpbuf != NULL)
    {
      jmp_buf *halt_buf = engine->jmpbuf;
      engine->last_cpu = last_cpu;
      engine->next_cpu = next_cpu;
      engine->reason = reason;
      engine->sigrc = sigrc;

      SIM_ENGINE_HALT_HOOK (sd, last_cpu, cia);

#ifdef SIM_CPU_EXCEPTION_SUSPEND
      if (last_cpu != NULL && reason != sim_exited)
	SIM_CPU_EXCEPTION_SUSPEND (sd, last_cpu, sim_signal_to_host (sd, sigrc));
#endif

      longjmp (*halt_buf, sim_engine_halt_jmpval);
    }
  else
    {
      sim_io_error (sd, "sim_halt - bad long jump");
      abort ();
    }
}


/* Generic restart */

void
sim_engine_restart (SIM_DESC sd,
		    sim_cpu *last_cpu,
		    sim_cpu *next_cpu,
		    sim_cia cia)
{
  sim_engine *engine = STATE_ENGINE (sd);
  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  if (engine->jmpbuf != NULL)
    {
      jmp_buf *halt_buf = engine->jmpbuf;
      engine->last_cpu = last_cpu;
      engine->next_cpu = next_cpu;
      SIM_ENGINE_RESTART_HOOK (sd, last_cpu, cia);
      longjmp (*halt_buf, sim_engine_restart_jmpval);
    }
  else
    sim_io_error (sd, "sim_restart - bad long jump");
}


/* Generic error code */

void
sim_engine_vabort (SIM_DESC sd,
		   sim_cpu *cpu,
		   sim_cia cia,
		   const char *fmt,
		   va_list ap)
{
  ASSERT (sd == NULL || STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  if (sd == NULL)
    {
      vfprintf (stderr, fmt, ap);
      fprintf (stderr, "\nQuit\n");
      abort ();
    }
  else if (STATE_ENGINE (sd)->jmpbuf == NULL)
    {
      sim_io_evprintf (sd, fmt, ap);
      sim_io_eprintf (sd, "\n");
      sim_io_error (sd, "Quit Simulator");
      abort ();
    }
  else
    {
      sim_io_evprintf (sd, fmt, ap);
      sim_io_eprintf (sd, "\n");
      sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGABRT);
    }
}

void
sim_engine_abort (SIM_DESC sd,
		  sim_cpu *cpu,
		  sim_cia cia,
		  const char *fmt,
		  ...)
{
  va_list ap;
  ASSERT (sd == NULL || STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  va_start(ap, fmt);
  sim_engine_vabort (sd, cpu, cia, fmt, ap);
  va_end (ap);
}


/* Generic next/last cpu */

int
sim_engine_last_cpu_nr (SIM_DESC sd)
{
  sim_engine *engine = STATE_ENGINE (sd);
  if (engine->last_cpu != NULL)
    return engine->last_cpu - STATE_CPU (sd, 0);
  else
    return MAX_NR_PROCESSORS;
}

int
sim_engine_next_cpu_nr (SIM_DESC sd)
{
  sim_engine *engine = STATE_ENGINE (sd);
  if (engine->next_cpu != NULL)
    return engine->next_cpu - STATE_CPU (sd, 0);
  else
    return sim_engine_last_cpu_nr (sd) + 1;
}

int
sim_engine_nr_cpus (SIM_DESC sd)
{
  sim_engine *engine = STATE_ENGINE (sd);
  return engine->nr_cpus;
}




/* Initialization */

static SIM_RC
sim_engine_init (SIM_DESC sd)
{
  /* initialize the start/stop/resume engine */
  sim_engine *engine = STATE_ENGINE (sd);
  engine->jmpbuf = NULL;
  engine->last_cpu = NULL;
  engine->next_cpu = NULL;
  engine->nr_cpus = MAX_NR_PROCESSORS;
  engine->reason = sim_running;
  engine->sigrc = 0;
  engine->stepper = NULL; /* sim_events_init will clean it up */
  return SIM_RC_OK;
}


SIM_RC
sim_engine_install (SIM_DESC sd)
{
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  sim_module_add_init_fn (sd, sim_engine_init);
  return SIM_RC_OK;
}
