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