/* gdb-if.c -- sim interface to GDB.

Copyright (C) 2011-2021 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.

This file is part of the GNU simulators.

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 <stdio.h>
#include <assert.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#include "ansidecl.h"
#include "libiberty.h"
#include "sim/callback.h"
#include "sim/sim.h"
#include "gdb/signals.h"
#include "gdb/sim-rl78.h"

#include "cpu.h"
#include "mem.h"
#include "load.h"
#include "trace.h"

/* Ideally, we'd wrap up all the minisim's data structures in an
   object and pass that around.  However, neither GDB nor run needs
   that ability.

   So we just have one instance, that lives in global variables, and
   each time we open it, we re-initialize it.  */

struct sim_state
{
  const char *message;
};

static struct sim_state the_minisim = {
  "This is the sole rl78 minisim instance."
};

static int is_open;

static struct host_callback_struct *host_callbacks;

/* Open an instance of the sim.  For this sim, only one instance
   is permitted.  If sim_open() is called multiple times, the sim
   will be reset.  */

SIM_DESC
sim_open (SIM_OPEN_KIND kind,
	  struct host_callback_struct *callback,
	  struct bfd *abfd, char * const *argv)
{
  if (is_open)
    fprintf (stderr, "rl78 minisim: re-opened sim\n");

  /* The 'run' interface doesn't use this function, so we don't care
     about KIND; it's always SIM_OPEN_DEBUG.  */
  if (kind != SIM_OPEN_DEBUG)
    fprintf (stderr, "rl78 minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n",
	     kind);

  /* We use this for the load command.  Perhaps someday, it'll be used
     for syscalls too.  */
  host_callbacks = callback;

  /* We don't expect any command-line arguments.  */

  init_cpu ();
  trace = 0;

  sim_disasm_init (abfd);
  is_open = 1;

  while (argv != NULL && *argv != NULL)
    {
      if (strcmp (*argv, "g10") == 0 || strcmp (*argv, "-Mg10") == 0)
	{
	  fprintf (stderr, "rl78 g10 support enabled.\n");
	  rl78_g10_mode = 1;
	  g13_multiply = 0;
	  g14_multiply = 0;
	  mem_set_mirror (0, 0xf8000, 4096);
	  break;
	}
      if (strcmp (*argv, "g13") == 0 || strcmp (*argv, "-Mg13") == 0)
	{
	  fprintf (stderr, "rl78 g13 support enabled.\n");
	  rl78_g10_mode = 0;
	  g13_multiply = 1;
	  g14_multiply = 0;
	  break;
	}
      if (strcmp (*argv, "g14") == 0 || strcmp (*argv, "-Mg14") == 0)
	{
	  fprintf (stderr, "rl78 g14 support enabled.\n");
	  rl78_g10_mode = 0;
	  g13_multiply = 0;
	  g14_multiply = 1;
	  break;
	}
      argv++;
    }

  return &the_minisim;
}

/* Verify the sim descriptor.  Just print a message if the descriptor
   doesn't match.  Nothing bad will happen if the descriptor doesn't
   match because all of the state is global.  But if it doesn't
   match, that means there's a problem with the caller.  */

static void
check_desc (SIM_DESC sd)
{
  if (sd != &the_minisim)
    fprintf (stderr, "rl78 minisim: desc != &the_minisim\n");
}

/* Close the sim.  */

void
sim_close (SIM_DESC sd, int quitting)
{
  check_desc (sd);

  /* Not much to do.  At least free up our memory.  */
  init_mem ();

  is_open = 0;
}

/* Open the program to run; print a message if the program cannot
   be opened.  */

static bfd *
open_objfile (const char *filename)
{
  bfd *prog = bfd_openr (filename, 0);

  if (!prog)
    {
      fprintf (stderr, "Can't read %s\n", filename);
      return 0;
    }

  if (!bfd_check_format (prog, bfd_object))
    {
      fprintf (stderr, "%s not a rl78 program\n", filename);
      return 0;
    }

  return prog;
}

/* Load a program.  */

SIM_RC
sim_load (SIM_DESC sd, const char *prog, struct bfd *abfd, int from_tty)
{
  check_desc (sd);

  if (!abfd)
    abfd = open_objfile (prog);
  if (!abfd)
    return SIM_RC_FAIL;

  rl78_load (abfd, host_callbacks, "sim");

  return SIM_RC_OK;
}

/* Create inferior.  */

SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
		     char * const *argv, char * const *env)
{
  check_desc (sd);

  if (abfd)
    rl78_load (abfd, 0, "sim");

  return SIM_RC_OK;
}

/* Read memory.  */

int
sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
{
  check_desc (sd);

  if (mem >= MEM_SIZE)
    return 0;
  else if (mem + length > MEM_SIZE)
    length = MEM_SIZE - mem;

  mem_get_blk (mem, buf, length);
  return length;
}

/* Write memory.  */

int
sim_write (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length)
{
  check_desc (sd);

  if (mem >= MEM_SIZE)
    return 0;
  else if (mem + length > MEM_SIZE)
    length = MEM_SIZE - mem;

  mem_put_blk (mem, buf, length);
  return length;
}

/* Read the LENGTH bytes at BUF as an little-endian value.  */

static SI
get_le (unsigned char *buf, int length)
{
  SI acc = 0;

  while (--length >= 0)
    acc = (acc << 8) + buf[length];

  return acc;
}

/* Store VAL as a little-endian value in the LENGTH bytes at BUF.  */

static void
put_le (unsigned char *buf, int length, SI val)
{
  int i;

  for (i = 0; i < length; i++)
    {
      buf[i] = val & 0xff;
      val >>= 8;
    }
}

/* Verify that REGNO is in the proper range.  Return 0 if not and
   something non-zero if so.  */

static int
check_regno (enum sim_rl78_regnum regno)
{
  return 0 <= regno && regno < sim_rl78_num_regs;
}

/* Return the size of the register REGNO.  */

static size_t
reg_size (enum sim_rl78_regnum regno)
{
  size_t size;

  if (regno == sim_rl78_pc_regnum)
    size = 4;
  else
    size = 1;

  return size;
}

/* Return the register address associated with the register specified by
   REGNO.  */

static unsigned long
reg_addr (enum sim_rl78_regnum regno)
{
  if (sim_rl78_bank0_r0_regnum <= regno
      && regno <= sim_rl78_bank0_r7_regnum)
    return 0xffef8 + (regno - sim_rl78_bank0_r0_regnum);
  else if (sim_rl78_bank1_r0_regnum <= regno
           && regno <= sim_rl78_bank1_r7_regnum)
    return 0xffef0 + (regno - sim_rl78_bank1_r0_regnum);
  else if (sim_rl78_bank2_r0_regnum <= regno
           && regno <= sim_rl78_bank2_r7_regnum)
    return 0xffee8 + (regno - sim_rl78_bank2_r0_regnum);
  else if (sim_rl78_bank3_r0_regnum <= regno
           && regno <= sim_rl78_bank3_r7_regnum)
    return 0xffee0 + (regno - sim_rl78_bank3_r0_regnum);
  else if (regno == sim_rl78_psw_regnum)
    return 0xffffa;
  else if (regno == sim_rl78_es_regnum)
    return 0xffffd;
  else if (regno == sim_rl78_cs_regnum)
    return 0xffffc;
  /* Note: We can't handle PC here because it's not memory mapped.  */
  else if (regno == sim_rl78_spl_regnum)
    return 0xffff8;
  else if (regno == sim_rl78_sph_regnum)
    return 0xffff9;
  else if (regno == sim_rl78_pmc_regnum)
    return 0xffffe;
  else if (regno == sim_rl78_mem_regnum)
    return 0xfffff;

  return 0;
}

/* Fetch the contents of the register specified by REGNO, placing the
   contents in BUF.  The length LENGTH must match the sim's internal
   notion of the register's size.  */

int
sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
{
  size_t size;
  SI val;

  check_desc (sd);

  if (!check_regno (regno))
    return 0;

  size = reg_size (regno);

  if (length != size)
    return 0;

  if (regno == sim_rl78_pc_regnum)
    val = pc;
  else
    val = memory[reg_addr (regno)];

  put_le (buf, length, val);

  return size;
}

/* Store the value stored in BUF to the register REGNO.  The length
   LENGTH must match the sim's internal notion of the register size.  */

int
sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
{
  size_t size;
  SI val;

  check_desc (sd);

  if (!check_regno (regno))
    return -1;

  size = reg_size (regno);

  if (length != size)
    return -1;

  val = get_le (buf, length);

  if (regno == sim_rl78_pc_regnum)
    {
      pc = val;

      /* The rl78 program counter is 20 bits wide.  Ensure that GDB
         hasn't picked up any stray bits.  This has occurred when performing
	 a GDB "return" command in which the return address is obtained
	 from a 32-bit container on the stack.  */
      assert ((pc & ~0x0fffff) == 0);
    }
  else
    memory[reg_addr (regno)] = val;
  return size;
}

/* Print out message associated with "info target".  */

void
sim_info (SIM_DESC sd, int verbose)
{
  check_desc (sd);

  printf ("The rl78 minisim doesn't collect any statistics.\n");
}

static volatile int stop;
static enum sim_stop reason;
int siggnal;


/* Given a signal number used by the rl78 bsp (that is, newlib),
   return the corresponding signal numbers.  */

static int
rl78_signal_to_target (int sig)
{
  switch (sig)
    {
    case 4:
      return GDB_SIGNAL_ILL;

    case 5:
      return GDB_SIGNAL_TRAP;

    case 10:
      return GDB_SIGNAL_BUS;

    case 11:
      return GDB_SIGNAL_SEGV;

    case 24:
      return GDB_SIGNAL_XCPU;
      break;

    case 2:
      return GDB_SIGNAL_INT;

    case 8:
      return GDB_SIGNAL_FPE;
      break;

    case 6:
      return GDB_SIGNAL_ABRT;
    }

  return 0;
}


/* Take a step return code RC and set up the variables consulted by
   sim_stop_reason appropriately.  */

static void
handle_step (int rc)
{
  if (RL78_STEPPED (rc) || RL78_HIT_BREAK (rc))
    {
      reason = sim_stopped;
      siggnal = GDB_SIGNAL_TRAP;
    }
  else if (RL78_STOPPED (rc))
    {
      reason = sim_stopped;
      siggnal = rl78_signal_to_target (RL78_STOP_SIG (rc));
    }
  else
    {
      assert (RL78_EXITED (rc));
      reason = sim_exited;
      siggnal = RL78_EXIT_STATUS (rc);
    }
}


/* Resume execution after a stop.  */

void
sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
{
  int rc;

  check_desc (sd);

  if (sig_to_deliver != 0)
    {
      fprintf (stderr,
	       "Warning: the rl78 minisim does not implement "
	       "signal delivery yet.\n" "Resuming with no signal.\n");
    }

      /* We don't clear 'stop' here, because then we would miss
         interrupts that arrived on the way here.  Instead, we clear
         the flag in sim_stop_reason, after GDB has disabled the
         interrupt signal handler.  */
  for (;;)
    {
      if (stop)
	{
	  stop = 0;
	  reason = sim_stopped;
	  siggnal = GDB_SIGNAL_INT;
	  break;
	}

      rc = setjmp (decode_jmp_buf);
      if (rc == 0)
	rc = decode_opcode ();

      if (!RL78_STEPPED (rc) || step)
	{
	  handle_step (rc);
	  break;
	}
    }
}

/* Stop the sim.  */

int
sim_stop (SIM_DESC sd)
{
  stop = 1;

  return 1;
}

/* Fetch the stop reason and signal.  */

void
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p)
{
  check_desc (sd);

  *reason_p = reason;
  *sigrc_p = siggnal;
}

/* Execute the sim-specific command associated with GDB's "sim ..."
   command.  */

void
sim_do_command (SIM_DESC sd, const char *cmd)
{
  const char *arg;
  char **argv = buildargv (cmd);

  check_desc (sd);

  cmd = arg = "";
  if (argv != NULL)
    {
      if (argv[0] != NULL)
	cmd = argv[0];
      if (argv[1] != NULL)
	arg = argv[1];
    }

  if (strcmp (cmd, "trace") == 0)
    {
      if (strcmp (arg, "on") == 0)
	trace = 1;
      else if (strcmp (arg, "off") == 0)
	trace = 0;
      else
	printf ("The 'sim trace' command expects 'on' or 'off' "
		"as an argument.\n");
    }
  else if (strcmp (cmd, "verbose") == 0)
    {
      if (strcmp (arg, "on") == 0)
	verbose = 1;
      else if (strcmp (arg, "noisy") == 0)
	verbose = 2;
      else if (strcmp (arg, "off") == 0)
	verbose = 0;
      else
	printf ("The 'sim verbose' command expects 'on', 'noisy', or 'off'"
		" as an argument.\n");
    }
  else
    printf ("The 'sim' command expects either 'trace' or 'verbose'"
	    " as a subcommand.\n");

  freeargv (argv);
}

/* Stub for command completion.  */

char **
sim_complete_command (SIM_DESC sd, const char *text, const char *word)
{
    return NULL;
}

char *
sim_memory_map (SIM_DESC sd)
{
  return NULL;
}
