1/* FRV simulator memory option handling. 2 Copyright (C) 1999, 2000, 2007, 2008, 2009, 2010, 2011 3 Free Software Foundation, Inc. 4 Contributed by Red Hat. 5 6This file is part of GDB, the GNU debugger. 7 8This program is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 3 of the License, or 11(at your option) any later version. 12 13This program is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along 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 41enum { 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 50static DECLARE_OPTION_HANDLER (frv_option_handler); 51 52const 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 78static char * 79parse_size (char *chp, address_word *nr_bytes) 80{ 81 /* <nr_bytes> */ 82 *nr_bytes = strtoul (chp, &chp, 0); 83 return chp; 84} 85 86static address_word 87check_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 99static void 100parse_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 133static SIM_RC 134frv_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} 238