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