/* FRV simulator memory option handling.
   Copyright (C) 1999-2021 Free Software Foundation, Inc.
   Contributed by Red Hat.

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"

#define WANT_CPU frvbf
#define WANT_CPU_FRVBF

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

#include <string.h>
#include <stdlib.h>

/* FRV specific command line options. */

enum {
  OPTION_FRV_DATA_CACHE = OPTION_START,
  OPTION_FRV_INSN_CACHE,
  OPTION_FRV_PROFILE_CACHE,
  OPTION_FRV_PROFILE_PARALLEL,
  OPTION_FRV_TIMER,
  OPTION_FRV_MEMORY_LATENCY
};

static DECLARE_OPTION_HANDLER (frv_option_handler);

const OPTION frv_options[] =
{
  { {"profile", optional_argument, NULL, 'p'},
      'p', "on|off", "Perform profiling",
      frv_option_handler },
  { {"data-cache", optional_argument, NULL, OPTION_FRV_DATA_CACHE },
      '\0', "WAYS[,SETS[,LINESIZE]]", "Enable data cache",
      frv_option_handler },
  { {"insn-cache", optional_argument, NULL, OPTION_FRV_INSN_CACHE },
      '\0', "WAYS[,SETS[,LINESIZE]]", "Enable instruction cache",
      frv_option_handler },
  { {"profile-cache", optional_argument, NULL, OPTION_FRV_PROFILE_CACHE },
      '\0', "on|off", "Profile caches",
      frv_option_handler },
  { {"profile-parallel", optional_argument, NULL, OPTION_FRV_PROFILE_PARALLEL },
      '\0', "on|off", "Profile parallelism",
      frv_option_handler },
  { {"timer", required_argument, NULL, OPTION_FRV_TIMER },
      '\0', "CYCLES,INTERRUPT", "Set Interrupt Timer",
      frv_option_handler },
  { {"memory-latency", required_argument, NULL, OPTION_FRV_MEMORY_LATENCY },
      '\0', "CYCLES", "Set Latency of memory",
      frv_option_handler },
  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
};

static char *
parse_size (char *chp, address_word *nr_bytes)
{
  /* <nr_bytes> */
  *nr_bytes = strtoul (chp, &chp, 0);
  return chp;
}

static address_word
check_pow2 (address_word value, char *argname, char *optname, SIM_DESC sd)
{
  if ((value & (value - 1)) != 0)
    {
      sim_io_eprintf (sd, "%s argument to %s must be a power of 2\n",
		      argname, optname);
      return 0; /* will enable default value.  */
    }

  return value;
}

static void
parse_cache_option (SIM_DESC sd, char *arg, char *cache_name, int is_data_cache)
{
  int i;
  address_word ways = 0, sets = 0, linesize = 0;
  if (arg != NULL)
    {
      char *chp = arg;
      /* parse the arguments */
      chp = parse_size (chp, &ways);
      ways = check_pow2 (ways, "WAYS", cache_name, sd);
      if (*chp == ',')
	{
	  chp = parse_size (chp + 1, &sets);
	  sets = check_pow2 (sets, "SETS", cache_name, sd);
	  if (*chp == ',')
	    {
	      chp = parse_size (chp + 1, &linesize);
	      linesize = check_pow2 (linesize, "LINESIZE", cache_name, sd);
	    }
	}
    }
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      SIM_CPU *current_cpu = STATE_CPU (sd, i);
      FRV_CACHE *cache = is_data_cache ? CPU_DATA_CACHE (current_cpu)
	                               : CPU_INSN_CACHE (current_cpu);
      cache->ways = ways;
      cache->sets = sets;
      cache->line_size = linesize;
      frv_cache_init (current_cpu, cache);
    }
}

static SIM_RC
frv_option_handler (SIM_DESC sd, sim_cpu *current_cpu, int opt,
		    char *arg, int is_command)
{
  switch (opt)
    {
    case 'p' :
      if (! WITH_PROFILE)
	sim_io_eprintf (sd, "Profiling not compiled in, `-p' ignored\n");
      else
	{
	  unsigned mask = PROFILE_USEFUL_MASK;
	  if (WITH_PROFILE_CACHE_P)
	    mask |= (1 << PROFILE_CACHE_IDX);
	  if (WITH_PROFILE_PARALLEL_P)
	    mask |= (1 << PROFILE_PARALLEL_IDX);
	  return set_profile_option_mask (sd, "profile", mask, arg);
	}
      break;

    case OPTION_FRV_DATA_CACHE:
      parse_cache_option (sd, arg, "data_cache", 1/*is_data_cache*/);
      return SIM_RC_OK;

    case OPTION_FRV_INSN_CACHE:
      parse_cache_option (sd, arg, "insn_cache", 0/*is_data_cache*/);
      return SIM_RC_OK;

    case OPTION_FRV_PROFILE_CACHE:
      if (WITH_PROFILE_CACHE_P)
	return sim_profile_set_option (sd, "-cache", PROFILE_CACHE_IDX, arg);
      else
	sim_io_eprintf (sd, "Cache profiling not compiled in, `--profile-cache' ignored\n");
      break;

    case OPTION_FRV_PROFILE_PARALLEL:
      if (WITH_PROFILE_PARALLEL_P)
	{
	  unsigned mask
	    = (1 << PROFILE_MODEL_IDX) | (1 << PROFILE_PARALLEL_IDX);
	  return set_profile_option_mask (sd, "-parallel", mask, arg);
	}
      else
	sim_io_eprintf (sd, "Parallel profiling not compiled in, `--profile-parallel' ignored\n");
      break;

    case OPTION_FRV_TIMER:
      {
	char *chp = arg;
	address_word cycles, interrupt;
	chp = parse_size (chp, &cycles);
	if (chp == arg)
	  {
	    sim_io_eprintf (sd, "Cycle count required for --timer\n");
	    return SIM_RC_FAIL;
	  }
	if (*chp != ',')
	  {
	    sim_io_eprintf (sd, "Interrupt number required for --timer\n");
	    return SIM_RC_FAIL;
	  }
	chp = parse_size (chp + 1, &interrupt);
	if (interrupt < 1 || interrupt > 15)
	  {
	    sim_io_eprintf (sd, "Interrupt number for --timer must be greater than 0 and less that 16\n");
	    return SIM_RC_FAIL;
	  }
	frv_interrupt_state.timer.enabled = 1;
	frv_interrupt_state.timer.value = cycles;
	frv_interrupt_state.timer.current = 0;
	frv_interrupt_state.timer.interrupt =
	  FRV_INTERRUPT_LEVEL_1 + interrupt - 1;
      }
      return SIM_RC_OK;

    case OPTION_FRV_MEMORY_LATENCY:
      {
	int i;
	char *chp = arg;
	address_word cycles;
	chp = parse_size (chp, &cycles);
	if (chp == arg)
	  {
	    sim_io_eprintf (sd, "Cycle count required for --memory-latency\n");
	    return SIM_RC_FAIL;
	  }
	for (i = 0; i < MAX_NR_PROCESSORS; ++i)
	  {
	    SIM_CPU *current_cpu = STATE_CPU (sd, i);
	    FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
	    FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
	    insn_cache->memory_latency = cycles;
	    data_cache->memory_latency = cycles;
	  }
      }
      return SIM_RC_OK;

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

    }

  return SIM_RC_FAIL;
}
