/* Generic simulator halt/restart.
   Copyright (C) 1997-2021 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/>.  */

/* This must come before any other includes.  */
#include "defs.h"

#include "sim-main.h"
#include "sim-assert.h"
#include "sim-signal.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;
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
SIM_RC sim_install_engine (SIM_DESC sd);

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