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