/* Generic simulator halt/restart.
   Copyright (C) 1997-2020 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.  */

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

#include <stdio.h>
#include <stdlib.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;
}
