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

Copyright (C) 2011-2013 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/>.  */

#include "config.h"
#include <stdio.h>
#include <assert.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#include "ansidecl.h"
#include "gdb/callback.h"
#include "gdb/remote-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 open;

static unsigned char hw_breakpoints[MEM_SIZE/8];

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 **argv)
{
  if (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);
  open = 1;
  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 ();

  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, 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 **argv, char **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;
  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.  */

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.  */

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;
	}

      if (hw_breakpoints[pc >> 3]
          && (hw_breakpoints[pc >> 3] & (1 << (pc & 0x7))))
	{
	  reason = sim_stopped;
	  siggnal = GDB_SIGNAL_TRAP;
	  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, char *cmd)
{
  char *args;

  check_desc (sd);

  if (cmd == NULL)
    {
      cmd = "";
      args = "";
    }
  else
    {
      char *p = cmd;

      /* Skip leading whitespace.  */
      while (isspace (*p))
	p++;

      /* Find the extent of the command word.  */
      for (p = cmd; *p; p++)
	if (isspace (*p))
	  break;

      /* Null-terminate the command word, and record the start of any
	 further arguments.  */
      if (*p)
	{
	  *p = '\0';
	  args = p + 1;
	  while (isspace (*args))
	    args++;
	}
      else
	args = p;
    }

  if (strcmp (cmd, "trace") == 0)
    {
      if (strcmp (args, "on") == 0)
	trace = 1;
      else if (strcmp (args, "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 (args, "on") == 0)
	verbose = 1;
      else if (strcmp (args, "noisy") == 0)
	verbose = 2;
      else if (strcmp (args, "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");
}

/* Stub for command completion.  */

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