/* Main simulator entry points specific to the OR1K.
   Copyright (C) 2017-2019 Free Software Foundation, Inc.

   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-options.h"
#include "libiberty.h"
#include "bfd.h"

#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

static void free_state (SIM_DESC);


/* Cover function of sim_state_free to free the cpu buffers as well.  */

static void
free_state (SIM_DESC sd)
{
  if (STATE_MODULES (sd) != NULL)
    sim_module_uninstall (sd);
  sim_cpu_free_all (sd);
  sim_state_free (sd);
}

/* Defaults for user passed arguments.  */
static const USI or1k_default_vr = 0x0;
static const USI or1k_default_upr = 0x0
  | SPR_FIELD_MASK_SYS_UPR_UP;
static const USI or1k_default_cpucfgr = 0x0
  | SPR_FIELD_MASK_SYS_CPUCFGR_OB32S
  | SPR_FIELD_MASK_SYS_CPUCFGR_OF32S;

static UWI or1k_upr;
static UWI or1k_vr;
static UWI or1k_cpucfgr;

enum
{
  OPTION_OR1K_VR,
  OPTION_OR1K_UPR,
  OPTION_OR1K_CPUCFGR = OPTION_START,
};

/* Setup help and handlers for the user defined arguments.  */
DECLARE_OPTION_HANDLER (or1k_option_handler);

static const OPTION or1k_options[] = {
  {{"or1k-cpucfgr", required_argument, NULL, OPTION_OR1K_CPUCFGR},
   '\0', "INTEGER|default", "Set simulator CPUCFGR value",
   or1k_option_handler},
  {{"or1k-vr", required_argument, NULL, OPTION_OR1K_VR},
   '\0', "INTEGER|default", "Set simulator VR value",
   or1k_option_handler},
  {{"or1k-upr", required_argument, NULL, OPTION_OR1K_UPR},
   '\0', "INTEGER|default", "Set simulator UPR value",
   or1k_option_handler},
  {{NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL}
};

/* Handler for parsing user defined arguments.  Currently we support
   configuring some of the CPU implementation specific registers including
   the Version Register (VR), the Unit Present Register (UPR) and the CPU
   Configuration Register (CPUCFGR).  */
SIM_RC
or1k_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg,
		     int is_command)
{
  switch (opt)
    {
    case OPTION_OR1K_VR:
      if (strcmp ("default", arg) == 0)
	or1k_vr = or1k_default_vr;
      else
	{
	  unsigned long long n;
	  char *endptr;

	  n = strtoull (arg, &endptr, 0);
	  if (*arg != '\0' && *endptr == '\0')
	    or1k_vr = n;
	  else
	    return SIM_RC_FAIL;
	}
      return SIM_RC_OK;

    case OPTION_OR1K_UPR:
      if (strcmp ("default", arg) == 0)
	or1k_upr = or1k_default_upr;
      else
	{
	  unsigned long long n;
	  char *endptr;

	  n = strtoull (arg, &endptr, 0);
	  if (*arg != '\0' && *endptr == '\0')
	    or1k_upr = n;
	  else
	    {
	      sim_io_eprintf
		(sd, "invalid argument to option --or1k-upr: `%s'\n", arg);
	      return SIM_RC_FAIL;
	    }
	}
      return SIM_RC_OK;

    case OPTION_OR1K_CPUCFGR:
      if (strcmp ("default", arg) == 0)
	or1k_cpucfgr = or1k_default_cpucfgr;
      else
	{
	  unsigned long long n;
	  char *endptr;

	  n = strtoull (arg, &endptr, 0);
	  if (*arg != '\0' && *endptr == '\0')
	    or1k_cpucfgr = n;
	  else
	    {
	      sim_io_eprintf
		(sd, "invalid argument to option --or1k-cpucfgr: `%s'\n", arg);
	      return SIM_RC_FAIL;
	    }
	}
      return SIM_RC_OK;

    default:
      sim_io_eprintf (sd, "Unknown or1k option %d\n", opt);
      return SIM_RC_FAIL;
    }

  return SIM_RC_FAIL;
}

/* Create an instance of the simulator.  */

SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
	  char * const *argv)
{
  SIM_DESC sd = sim_state_alloc (kind, callback);
  char c;
  int i;

  /* The cpu data is kept in a separately allocated chunk of memory.  */
  if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Perform initial sim setups.  */
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  or1k_upr = or1k_default_upr;
  or1k_vr = or1k_default_vr;
  or1k_cpucfgr = or1k_default_cpucfgr;
  sim_add_option_table (sd, NULL, or1k_options);

  /* Parse the user passed arguments.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Allocate core managed memory if none specified by user.
     Use address 4 here in case the user wanted address 0 unmapped.  */
  if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
    {
      sim_do_commandf (sd, "memory region 0,0x%x", OR1K_DEFAULT_MEM_SIZE);
    }

  /* Check for/establish the reference program image.  */
  if (sim_analyze_program (sd,
			   (STATE_PROG_ARGV (sd) != NULL
			    ? *STATE_PROG_ARGV (sd)
			    : NULL), abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Establish any remaining configuration options.  */
  if (sim_config (sd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Make sure delay slot mode is consistent with the loaded binary.  */
  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_or1knd)
    or1k_cpucfgr |= SPR_FIELD_MASK_SYS_CPUCFGR_ND;
  else
    or1k_cpucfgr &= ~SPR_FIELD_MASK_SYS_CPUCFGR_ND;

  /* Open a copy of the cpu descriptor table and initialize the
     disassembler.  These initialization functions are generated by CGEN
     using the binutils scheme cpu description files.  */
  {
    CGEN_CPU_DESC cd =
      or1k_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
			    CGEN_ENDIAN_BIG);
    for (i = 0; i < MAX_NR_PROCESSORS; ++i)
      {
	SIM_CPU *cpu = STATE_CPU (sd, i);
	CPU_CPU_DESC (cpu) = cd;
	CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
      }
    or1k_cgen_init_dis (cd);
  }

  /* Initialize various cgen things not done by common framework.
     Must be done after or1k_cgen_cpu_open.  */
  cgen_init (sd);

  /* Do some final OpenRISC sim specific initializations.  */
  for (c = 0; c < MAX_NR_PROCESSORS; ++c)
    {
      SIM_CPU *cpu = STATE_CPU (sd, i);
      /* Only needed for profiling, but the structure member is small.  */
      memset (CPU_OR1K_MISC_PROFILE (cpu), 0,
	      sizeof (*CPU_OR1K_MISC_PROFILE (cpu)));

      or1k_cpu_init (sd, cpu, or1k_vr, or1k_upr, or1k_cpucfgr);
    }

  return sd;
}


SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
		     char * const *argv, char * const *envp)
{
  SIM_CPU *current_cpu = STATE_CPU (sd, 0);
  SIM_ADDR addr;

  if (abfd != NULL)
    addr = bfd_get_start_address (abfd);
  else
    addr = 0;
  sim_pc_set (current_cpu, addr);

  return SIM_RC_OK;
}
