Blame sim/frv/options.c

Packit Service 706eca
/* FRV simulator memory option handling.
Packit Service 706eca
   Copyright (C) 1999-2018 Free Software Foundation, Inc.
Packit Service 706eca
   Contributed by Red Hat.
Packit Service 706eca
Packit Service 706eca
This file is part of GDB, the GNU debugger.
Packit Service 706eca
Packit Service 706eca
This program is free software; you can redistribute it and/or modify
Packit Service 706eca
it under the terms of the GNU General Public License as published by
Packit Service 706eca
the Free Software Foundation; either version 3 of the License, or
Packit Service 706eca
(at your option) any later version.
Packit Service 706eca
Packit Service 706eca
This program is distributed in the hope that it will be useful,
Packit Service 706eca
but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 706eca
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 706eca
GNU General Public License for more details.
Packit Service 706eca
Packit Service 706eca
You should have received a copy of the GNU General Public License
Packit Service 706eca
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service 706eca
Packit Service 706eca
#define WANT_CPU frvbf
Packit Service 706eca
#define WANT_CPU_FRVBF
Packit Service 706eca
Packit Service 706eca
#include "sim-main.h"
Packit Service 706eca
#include "sim-assert.h"
Packit Service 706eca
#include "sim-options.h"
Packit Service 706eca
Packit Service 706eca
#ifdef HAVE_STRING_H
Packit Service 706eca
#include <string.h>
Packit Service 706eca
#else
Packit Service 706eca
#ifdef HAVE_STRINGS_H
Packit Service 706eca
#include <strings.h>
Packit Service 706eca
#endif
Packit Service 706eca
#endif
Packit Service 706eca
#ifdef HAVE_STDLIB_H
Packit Service 706eca
#include <stdlib.h>
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
/* FRV specific command line options. */
Packit Service 706eca
Packit Service 706eca
enum {
Packit Service 706eca
  OPTION_FRV_DATA_CACHE = OPTION_START,
Packit Service 706eca
  OPTION_FRV_INSN_CACHE,
Packit Service 706eca
  OPTION_FRV_PROFILE_CACHE,
Packit Service 706eca
  OPTION_FRV_PROFILE_PARALLEL,
Packit Service 706eca
  OPTION_FRV_TIMER,
Packit Service 706eca
  OPTION_FRV_MEMORY_LATENCY
Packit Service 706eca
};
Packit Service 706eca
Packit Service 706eca
static DECLARE_OPTION_HANDLER (frv_option_handler);
Packit Service 706eca
Packit Service 706eca
const OPTION frv_options[] =
Packit Service 706eca
{
Packit Service 706eca
  { {"profile", optional_argument, NULL, 'p'},
Packit Service 706eca
      'p', "on|off", "Perform profiling",
Packit Service 706eca
      frv_option_handler },
Packit Service 706eca
  { {"data-cache", optional_argument, NULL, OPTION_FRV_DATA_CACHE },
Packit Service 706eca
      '\0', "WAYS[,SETS[,LINESIZE]]", "Enable data cache",
Packit Service 706eca
      frv_option_handler },
Packit Service 706eca
  { {"insn-cache", optional_argument, NULL, OPTION_FRV_INSN_CACHE },
Packit Service 706eca
      '\0', "WAYS[,SETS[,LINESIZE]]", "Enable instruction cache",
Packit Service 706eca
      frv_option_handler },
Packit Service 706eca
  { {"profile-cache", optional_argument, NULL, OPTION_FRV_PROFILE_CACHE },
Packit Service 706eca
      '\0', "on|off", "Profile caches",
Packit Service 706eca
      frv_option_handler },
Packit Service 706eca
  { {"profile-parallel", optional_argument, NULL, OPTION_FRV_PROFILE_PARALLEL },
Packit Service 706eca
      '\0', "on|off", "Profile parallelism",
Packit Service 706eca
      frv_option_handler },
Packit Service 706eca
  { {"timer", required_argument, NULL, OPTION_FRV_TIMER },
Packit Service 706eca
      '\0', "CYCLES,INTERRUPT", "Set Interrupt Timer",
Packit Service 706eca
      frv_option_handler },
Packit Service 706eca
  { {"memory-latency", required_argument, NULL, OPTION_FRV_MEMORY_LATENCY },
Packit Service 706eca
      '\0', "CYCLES", "Set Latency of memory",
Packit Service 706eca
      frv_option_handler },
Packit Service 706eca
  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
Packit Service 706eca
};
Packit Service 706eca
Packit Service 706eca
static char *
Packit Service 706eca
parse_size (char *chp, address_word *nr_bytes)
Packit Service 706eca
{
Packit Service 706eca
  /* <nr_bytes> */
Packit Service 706eca
  *nr_bytes = strtoul (chp, &chp, 0);
Packit Service 706eca
  return chp;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static address_word
Packit Service 706eca
check_pow2 (address_word value, char *argname, char *optname, SIM_DESC sd)
Packit Service 706eca
{
Packit Service 706eca
  if ((value & (value - 1)) != 0)
Packit Service 706eca
    {
Packit Service 706eca
      sim_io_eprintf (sd, "%s argument to %s must be a power of 2\n",
Packit Service 706eca
		      argname, optname);
Packit Service 706eca
      return 0; /* will enable default value.  */
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  return value;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
parse_cache_option (SIM_DESC sd, char *arg, char *cache_name, int is_data_cache)
Packit Service 706eca
{
Packit Service 706eca
  int i;
Packit Service 706eca
  address_word ways = 0, sets = 0, linesize = 0;
Packit Service 706eca
  if (arg != NULL)
Packit Service 706eca
    {
Packit Service 706eca
      char *chp = arg;
Packit Service 706eca
      /* parse the arguments */
Packit Service 706eca
      chp = parse_size (chp, &ways);
Packit Service 706eca
      ways = check_pow2 (ways, "WAYS", cache_name, sd);
Packit Service 706eca
      if (*chp == ',')
Packit Service 706eca
	{
Packit Service 706eca
	  chp = parse_size (chp + 1, &sets;;
Packit Service 706eca
	  sets = check_pow2 (sets, "SETS", cache_name, sd);
Packit Service 706eca
	  if (*chp == ',')
Packit Service 706eca
	    {
Packit Service 706eca
	      chp = parse_size (chp + 1, &linesize);
Packit Service 706eca
	      linesize = check_pow2 (linesize, "LINESIZE", cache_name, sd);
Packit Service 706eca
	    }
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
Packit Service 706eca
    {
Packit Service 706eca
      SIM_CPU *current_cpu = STATE_CPU (sd, i);
Packit Service 706eca
      FRV_CACHE *cache = is_data_cache ? CPU_DATA_CACHE (current_cpu)
Packit Service 706eca
	                               : CPU_INSN_CACHE (current_cpu);
Packit Service 706eca
      cache->ways = ways;
Packit Service 706eca
      cache->sets = sets;
Packit Service 706eca
      cache->line_size = linesize;
Packit Service 706eca
      frv_cache_init (current_cpu, cache);
Packit Service 706eca
    }
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static SIM_RC
Packit Service 706eca
frv_option_handler (SIM_DESC sd, sim_cpu *current_cpu, int opt,
Packit Service 706eca
		    char *arg, int is_command)
Packit Service 706eca
{
Packit Service 706eca
  switch (opt)
Packit Service 706eca
    {
Packit Service 706eca
    case 'p' :
Packit Service 706eca
      if (! WITH_PROFILE)
Packit Service 706eca
	sim_io_eprintf (sd, "Profiling not compiled in, `-p' ignored\n");
Packit Service 706eca
      else
Packit Service 706eca
	{
Packit Service 706eca
	  unsigned mask = PROFILE_USEFUL_MASK;
Packit Service 706eca
	  if (WITH_PROFILE_CACHE_P)
Packit Service 706eca
	    mask |= (1 << PROFILE_CACHE_IDX);
Packit Service 706eca
	  if (WITH_PROFILE_PARALLEL_P)
Packit Service 706eca
	    mask |= (1 << PROFILE_PARALLEL_IDX);
Packit Service 706eca
	  return set_profile_option_mask (sd, "profile", mask, arg);
Packit Service 706eca
	}
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case OPTION_FRV_DATA_CACHE:
Packit Service 706eca
      parse_cache_option (sd, arg, "data_cache", 1/*is_data_cache*/);
Packit Service 706eca
      return SIM_RC_OK;
Packit Service 706eca
Packit Service 706eca
    case OPTION_FRV_INSN_CACHE:
Packit Service 706eca
      parse_cache_option (sd, arg, "insn_cache", 0/*is_data_cache*/);
Packit Service 706eca
      return SIM_RC_OK;
Packit Service 706eca
Packit Service 706eca
    case OPTION_FRV_PROFILE_CACHE:
Packit Service 706eca
      if (WITH_PROFILE_CACHE_P)
Packit Service 706eca
	return sim_profile_set_option (sd, "-cache", PROFILE_CACHE_IDX, arg);
Packit Service 706eca
      else
Packit Service 706eca
	sim_io_eprintf (sd, "Cache profiling not compiled in, `--profile-cache' ignored\n");
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case OPTION_FRV_PROFILE_PARALLEL:
Packit Service 706eca
      if (WITH_PROFILE_PARALLEL_P)
Packit Service 706eca
	{
Packit Service 706eca
	  unsigned mask
Packit Service 706eca
	    = (1 << PROFILE_MODEL_IDX) | (1 << PROFILE_PARALLEL_IDX);
Packit Service 706eca
	  return set_profile_option_mask (sd, "-parallel", mask, arg);
Packit Service 706eca
	}
Packit Service 706eca
      else
Packit Service 706eca
	sim_io_eprintf (sd, "Parallel profiling not compiled in, `--profile-parallel' ignored\n");
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case OPTION_FRV_TIMER:
Packit Service 706eca
      {
Packit Service 706eca
	char *chp = arg;
Packit Service 706eca
	address_word cycles, interrupt;
Packit Service 706eca
	chp = parse_size (chp, &cycles);
Packit Service 706eca
	if (chp == arg)
Packit Service 706eca
	  {
Packit Service 706eca
	    sim_io_eprintf (sd, "Cycle count required for --timer\n");
Packit Service 706eca
	    return SIM_RC_FAIL;
Packit Service 706eca
	  }
Packit Service 706eca
	if (*chp != ',')
Packit Service 706eca
	  {
Packit Service 706eca
	    sim_io_eprintf (sd, "Interrupt number required for --timer\n");
Packit Service 706eca
	    return SIM_RC_FAIL;
Packit Service 706eca
	  }
Packit Service 706eca
	chp = parse_size (chp + 1, &interrupt);
Packit Service 706eca
	if (interrupt < 1 || interrupt > 15)
Packit Service 706eca
	  {
Packit Service 706eca
	    sim_io_eprintf (sd, "Interrupt number for --timer must be greater than 0 and less that 16\n");
Packit Service 706eca
	    return SIM_RC_FAIL;
Packit Service 706eca
	  }
Packit Service 706eca
	frv_interrupt_state.timer.enabled = 1;
Packit Service 706eca
	frv_interrupt_state.timer.value = cycles;
Packit Service 706eca
	frv_interrupt_state.timer.current = 0;
Packit Service 706eca
	frv_interrupt_state.timer.interrupt =
Packit Service 706eca
	  FRV_INTERRUPT_LEVEL_1 + interrupt - 1;
Packit Service 706eca
      }
Packit Service 706eca
      return SIM_RC_OK;
Packit Service 706eca
Packit Service 706eca
    case OPTION_FRV_MEMORY_LATENCY:
Packit Service 706eca
      {
Packit Service 706eca
	int i;
Packit Service 706eca
	char *chp = arg;
Packit Service 706eca
	address_word cycles;
Packit Service 706eca
	chp = parse_size (chp, &cycles);
Packit Service 706eca
	if (chp == arg)
Packit Service 706eca
	  {
Packit Service 706eca
	    sim_io_eprintf (sd, "Cycle count required for --memory-latency\n");
Packit Service 706eca
	    return SIM_RC_FAIL;
Packit Service 706eca
	  }
Packit Service 706eca
	for (i = 0; i < MAX_NR_PROCESSORS; ++i)
Packit Service 706eca
	  {
Packit Service 706eca
	    SIM_CPU *current_cpu = STATE_CPU (sd, i);
Packit Service 706eca
	    FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
Packit Service 706eca
	    FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
Packit Service 706eca
	    insn_cache->memory_latency = cycles;
Packit Service 706eca
	    data_cache->memory_latency = cycles;
Packit Service 706eca
	  }
Packit Service 706eca
      }
Packit Service 706eca
      return SIM_RC_OK;
Packit Service 706eca
Packit Service 706eca
    default:
Packit Service 706eca
      sim_io_eprintf (sd, "Unknown FRV option %d\n", opt);
Packit Service 706eca
      return SIM_RC_FAIL;
Packit Service 706eca
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  return SIM_RC_FAIL;
Packit Service 706eca
}