xref: /netbsd-src/external/gpl3/gdb/dist/sim/frv/options.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /* FRV simulator memory option handling.
2    Copyright (C) 1999-2014 Free Software Foundation, Inc.
3    Contributed by Red Hat.
4 
5 This file is part of GDB, the GNU debugger.
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #define WANT_CPU frvbf
21 #define WANT_CPU_FRVBF
22 
23 #include "sim-main.h"
24 #include "sim-assert.h"
25 #include "sim-options.h"
26 
27 #ifdef HAVE_STRING_H
28 #include <string.h>
29 #else
30 #ifdef HAVE_STRINGS_H
31 #include <strings.h>
32 #endif
33 #endif
34 #ifdef HAVE_STDLIB_H
35 #include <stdlib.h>
36 #endif
37 
38 /* FRV specific command line options. */
39 
40 enum {
41   OPTION_FRV_DATA_CACHE = OPTION_START,
42   OPTION_FRV_INSN_CACHE,
43   OPTION_FRV_PROFILE_CACHE,
44   OPTION_FRV_PROFILE_PARALLEL,
45   OPTION_FRV_TIMER,
46   OPTION_FRV_MEMORY_LATENCY
47 };
48 
49 static DECLARE_OPTION_HANDLER (frv_option_handler);
50 
51 const OPTION frv_options[] =
52 {
53   { {"profile", optional_argument, NULL, 'p'},
54       'p', "on|off", "Perform profiling",
55       frv_option_handler },
56   { {"data-cache", optional_argument, NULL, OPTION_FRV_DATA_CACHE },
57       '\0', "WAYS[,SETS[,LINESIZE]]", "Enable data cache",
58       frv_option_handler },
59   { {"insn-cache", optional_argument, NULL, OPTION_FRV_INSN_CACHE },
60       '\0', "WAYS[,SETS[,LINESIZE]]", "Enable instruction cache",
61       frv_option_handler },
62   { {"profile-cache", optional_argument, NULL, OPTION_FRV_PROFILE_CACHE },
63       '\0', "on|off", "Profile caches",
64       frv_option_handler },
65   { {"profile-parallel", optional_argument, NULL, OPTION_FRV_PROFILE_PARALLEL },
66       '\0', "on|off", "Profile parallelism",
67       frv_option_handler },
68   { {"timer", required_argument, NULL, OPTION_FRV_TIMER },
69       '\0', "CYCLES,INTERRUPT", "Set Interrupt Timer",
70       frv_option_handler },
71   { {"memory-latency", required_argument, NULL, OPTION_FRV_MEMORY_LATENCY },
72       '\0', "CYCLES", "Set Latency of memory",
73       frv_option_handler },
74   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
75 };
76 
77 static char *
78 parse_size (char *chp, address_word *nr_bytes)
79 {
80   /* <nr_bytes> */
81   *nr_bytes = strtoul (chp, &chp, 0);
82   return chp;
83 }
84 
85 static address_word
86 check_pow2 (address_word value, char *argname, char *optname, SIM_DESC sd)
87 {
88   if ((value & (value - 1)) != 0)
89     {
90       sim_io_eprintf (sd, "%s argument to %s must be a power of 2\n",
91 		      argname, optname);
92       return 0; /* will enable default value.  */
93     }
94 
95   return value;
96 }
97 
98 static void
99 parse_cache_option (SIM_DESC sd, char *arg, char *cache_name, int is_data_cache)
100 {
101   int i;
102   address_word ways = 0, sets = 0, linesize = 0;
103   if (arg != NULL)
104     {
105       char *chp = arg;
106       /* parse the arguments */
107       chp = parse_size (chp, &ways);
108       ways = check_pow2 (ways, "WAYS", cache_name, sd);
109       if (*chp == ',')
110 	{
111 	  chp = parse_size (chp + 1, &sets);
112 	  sets = check_pow2 (sets, "SETS", cache_name, sd);
113 	  if (*chp == ',')
114 	    {
115 	      chp = parse_size (chp + 1, &linesize);
116 	      linesize = check_pow2 (linesize, "LINESIZE", cache_name, sd);
117 	    }
118 	}
119     }
120   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
121     {
122       SIM_CPU *current_cpu = STATE_CPU (sd, i);
123       FRV_CACHE *cache = is_data_cache ? CPU_DATA_CACHE (current_cpu)
124 	                               : CPU_INSN_CACHE (current_cpu);
125       cache->ways = ways;
126       cache->sets = sets;
127       cache->line_size = linesize;
128       frv_cache_init (current_cpu, cache);
129     }
130 }
131 
132 static SIM_RC
133 frv_option_handler (SIM_DESC sd, sim_cpu *current_cpu, int opt,
134 		    char *arg, int is_command)
135 {
136   switch (opt)
137     {
138     case 'p' :
139       if (! WITH_PROFILE)
140 	sim_io_eprintf (sd, "Profiling not compiled in, `-p' ignored\n");
141       else
142 	{
143 	  unsigned mask = PROFILE_USEFUL_MASK;
144 	  if (WITH_PROFILE_CACHE_P)
145 	    mask |= (1 << PROFILE_CACHE_IDX);
146 	  if (WITH_PROFILE_PARALLEL_P)
147 	    mask |= (1 << PROFILE_PARALLEL_IDX);
148 	  return set_profile_option_mask (sd, "profile", mask, arg);
149 	}
150       break;
151 
152     case OPTION_FRV_DATA_CACHE:
153       parse_cache_option (sd, arg, "data_cache", 1/*is_data_cache*/);
154       return SIM_RC_OK;
155 
156     case OPTION_FRV_INSN_CACHE:
157       parse_cache_option (sd, arg, "insn_cache", 0/*is_data_cache*/);
158       return SIM_RC_OK;
159 
160     case OPTION_FRV_PROFILE_CACHE:
161       if (WITH_PROFILE_CACHE_P)
162 	return sim_profile_set_option (sd, "-cache", PROFILE_CACHE_IDX, arg);
163       else
164 	sim_io_eprintf (sd, "Cache profiling not compiled in, `--profile-cache' ignored\n");
165       break;
166 
167     case OPTION_FRV_PROFILE_PARALLEL:
168       if (WITH_PROFILE_PARALLEL_P)
169 	{
170 	  unsigned mask
171 	    = (1 << PROFILE_MODEL_IDX) | (1 << PROFILE_PARALLEL_IDX);
172 	  return set_profile_option_mask (sd, "-parallel", mask, arg);
173 	}
174       else
175 	sim_io_eprintf (sd, "Parallel profiling not compiled in, `--profile-parallel' ignored\n");
176       break;
177 
178     case OPTION_FRV_TIMER:
179       {
180 	char *chp = arg;
181 	address_word cycles, interrupt;
182 	chp = parse_size (chp, &cycles);
183 	if (chp == arg)
184 	  {
185 	    sim_io_eprintf (sd, "Cycle count required for --timer\n");
186 	    return SIM_RC_FAIL;
187 	  }
188 	if (*chp != ',')
189 	  {
190 	    sim_io_eprintf (sd, "Interrupt number required for --timer\n");
191 	    return SIM_RC_FAIL;
192 	  }
193 	chp = parse_size (chp + 1, &interrupt);
194 	if (interrupt < 1 || interrupt > 15)
195 	  {
196 	    sim_io_eprintf (sd, "Interrupt number for --timer must be greater than 0 and less that 16\n");
197 	    return SIM_RC_FAIL;
198 	  }
199 	frv_interrupt_state.timer.enabled = 1;
200 	frv_interrupt_state.timer.value = cycles;
201 	frv_interrupt_state.timer.current = 0;
202 	frv_interrupt_state.timer.interrupt =
203 	  FRV_INTERRUPT_LEVEL_1 + interrupt - 1;
204       }
205       return SIM_RC_OK;
206 
207     case OPTION_FRV_MEMORY_LATENCY:
208       {
209 	int i;
210 	char *chp = arg;
211 	address_word cycles;
212 	chp = parse_size (chp, &cycles);
213 	if (chp == arg)
214 	  {
215 	    sim_io_eprintf (sd, "Cycle count required for --memory-latency\n");
216 	    return SIM_RC_FAIL;
217 	  }
218 	for (i = 0; i < MAX_NR_PROCESSORS; ++i)
219 	  {
220 	    SIM_CPU *current_cpu = STATE_CPU (sd, i);
221 	    FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
222 	    FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
223 	    insn_cache->memory_latency = cycles;
224 	    data_cache->memory_latency = cycles;
225 	  }
226       }
227       return SIM_RC_OK;
228 
229     default:
230       sim_io_eprintf (sd, "Unknown FRV option %d\n", opt);
231       return SIM_RC_FAIL;
232 
233     }
234 
235   return SIM_RC_FAIL;
236 }
237