1a5a4af3bSchristos /* Main simulator entry points specific to the M32R. 2*8b657b07Schristos Copyright (C) 1996-2023 Free Software Foundation, Inc. 3a5a4af3bSchristos Contributed by Cygnus Support. 4a5a4af3bSchristos 5a5a4af3bSchristos This file is part of GDB, the GNU debugger. 6a5a4af3bSchristos 7a5a4af3bSchristos This program is free software; you can redistribute it and/or modify 8a5a4af3bSchristos it under the terms of the GNU General Public License as published by 9a5a4af3bSchristos the Free Software Foundation; either version 3 of the License, or 10a5a4af3bSchristos (at your option) any later version. 11a5a4af3bSchristos 12a5a4af3bSchristos This program is distributed in the hope that it will be useful, 13a5a4af3bSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14a5a4af3bSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a5a4af3bSchristos GNU General Public License for more details. 16a5a4af3bSchristos 17a5a4af3bSchristos You should have received a copy of the GNU General Public License 18a5a4af3bSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19a5a4af3bSchristos 20*8b657b07Schristos /* This must come before any other includes. */ 21*8b657b07Schristos #include "defs.h" 22*8b657b07Schristos 23*8b657b07Schristos #include <string.h> 24*8b657b07Schristos #include <stdlib.h> 25*8b657b07Schristos 26*8b657b07Schristos #include "sim/callback.h" 27a5a4af3bSchristos #include "sim-main.h" 28a5a4af3bSchristos #include "sim-options.h" 29a5a4af3bSchristos #include "libiberty.h" 30a5a4af3bSchristos #include "bfd.h" 31a5a4af3bSchristos 32e5cb852cSchristos #include "dv-m32r_uart.h" 33e5cb852cSchristos 34*8b657b07Schristos #define M32R_DEFAULT_MEM_SIZE 0x2000000 /* 32M */ 35*8b657b07Schristos 36a5a4af3bSchristos static void free_state (SIM_DESC); 37a5a4af3bSchristos static void print_m32r_misc_cpu (SIM_CPU *cpu, int verbose); 38a5a4af3bSchristos 39a5a4af3bSchristos /* Cover function of sim_state_free to free the cpu buffers as well. */ 40a5a4af3bSchristos 41a5a4af3bSchristos static void 42a5a4af3bSchristos free_state (SIM_DESC sd) 43a5a4af3bSchristos { 44a5a4af3bSchristos if (STATE_MODULES (sd) != NULL) 45a5a4af3bSchristos sim_module_uninstall (sd); 46a5a4af3bSchristos sim_cpu_free_all (sd); 47a5a4af3bSchristos sim_state_free (sd); 48a5a4af3bSchristos } 49a5a4af3bSchristos 50*8b657b07Schristos extern const SIM_MACH * const m32r_sim_machs[]; 51*8b657b07Schristos 52a5a4af3bSchristos /* Create an instance of the simulator. */ 53a5a4af3bSchristos 54a5a4af3bSchristos SIM_DESC 55*8b657b07Schristos sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd, 56*8b657b07Schristos char * const *argv) 57a5a4af3bSchristos { 58a5a4af3bSchristos SIM_DESC sd = sim_state_alloc (kind, callback); 59a5a4af3bSchristos char c; 60a5a4af3bSchristos int i; 61a5a4af3bSchristos 62*8b657b07Schristos /* Set default options before parsing user options. */ 63*8b657b07Schristos STATE_MACHS (sd) = m32r_sim_machs; 64*8b657b07Schristos STATE_MODEL_NAME (sd) = "m32r/d"; 65*8b657b07Schristos current_alignment = STRICT_ALIGNMENT; 66*8b657b07Schristos current_target_byte_order = BFD_ENDIAN_BIG; 67*8b657b07Schristos 68a5a4af3bSchristos /* The cpu data is kept in a separately allocated chunk of memory. */ 69*8b657b07Schristos if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK) 70a5a4af3bSchristos { 71a5a4af3bSchristos free_state (sd); 72a5a4af3bSchristos return 0; 73a5a4af3bSchristos } 74a5a4af3bSchristos 75a5a4af3bSchristos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 76a5a4af3bSchristos { 77a5a4af3bSchristos free_state (sd); 78a5a4af3bSchristos return 0; 79a5a4af3bSchristos } 80a5a4af3bSchristos 81e5cb852cSchristos /* The parser will print an error message for us, so we silently return. */ 82a5a4af3bSchristos if (sim_parse_args (sd, argv) != SIM_RC_OK) 83a5a4af3bSchristos { 84a5a4af3bSchristos free_state (sd); 85a5a4af3bSchristos return 0; 86a5a4af3bSchristos } 87a5a4af3bSchristos 88a5a4af3bSchristos /* Allocate a handler for the control registers and other devices 89a5a4af3bSchristos if no memory for that range has been allocated by the user. 90a5a4af3bSchristos All are allocated in one chunk to keep things from being 91e5cb852cSchristos unnecessarily complicated. 92e5cb852cSchristos TODO: Move these to the sim-model framework. */ 93e5cb852cSchristos sim_hw_parse (sd, "/core/%s/reg %#x %i", "m32r_uart", UART_BASE_ADDR, 0x100); 94e5cb852cSchristos sim_hw_parse (sd, "/core/%s/reg %#x %i", "m32r_cache", 0xfffffff0, 0x10); 95a5a4af3bSchristos 96a5a4af3bSchristos /* Allocate core managed memory if none specified by user. 97a5a4af3bSchristos Use address 4 here in case the user wanted address 0 unmapped. */ 98a5a4af3bSchristos if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0) 99a5a4af3bSchristos sim_do_commandf (sd, "memory region 0,0x%x", M32R_DEFAULT_MEM_SIZE); 100a5a4af3bSchristos 101a5a4af3bSchristos /* check for/establish the reference program image */ 102*8b657b07Schristos if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 103a5a4af3bSchristos { 104a5a4af3bSchristos free_state (sd); 105a5a4af3bSchristos return 0; 106a5a4af3bSchristos } 107a5a4af3bSchristos 108a5a4af3bSchristos /* Establish any remaining configuration options. */ 109a5a4af3bSchristos if (sim_config (sd) != SIM_RC_OK) 110a5a4af3bSchristos { 111a5a4af3bSchristos free_state (sd); 112a5a4af3bSchristos return 0; 113a5a4af3bSchristos } 114a5a4af3bSchristos 115a5a4af3bSchristos if (sim_post_argv_init (sd) != SIM_RC_OK) 116a5a4af3bSchristos { 117a5a4af3bSchristos free_state (sd); 118a5a4af3bSchristos return 0; 119a5a4af3bSchristos } 120a5a4af3bSchristos 121a5a4af3bSchristos /* Open a copy of the cpu descriptor table. */ 122a5a4af3bSchristos { 123a5a4af3bSchristos CGEN_CPU_DESC cd = m32r_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name, 124a5a4af3bSchristos CGEN_ENDIAN_BIG); 125a5a4af3bSchristos for (i = 0; i < MAX_NR_PROCESSORS; ++i) 126a5a4af3bSchristos { 127a5a4af3bSchristos SIM_CPU *cpu = STATE_CPU (sd, i); 128a5a4af3bSchristos CPU_CPU_DESC (cpu) = cd; 129a5a4af3bSchristos CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn; 130a5a4af3bSchristos } 131a5a4af3bSchristos m32r_cgen_init_dis (cd); 132a5a4af3bSchristos } 133a5a4af3bSchristos 134a5a4af3bSchristos for (c = 0; c < MAX_NR_PROCESSORS; ++c) 135a5a4af3bSchristos { 136a5a4af3bSchristos /* Only needed for profiling, but the structure member is small. */ 137a5a4af3bSchristos memset (CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)), 0, 138a5a4af3bSchristos sizeof (* CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)))); 139a5a4af3bSchristos /* Hook in callback for reporting these stats */ 140a5a4af3bSchristos PROFILE_INFO_CPU_CALLBACK (CPU_PROFILE_DATA (STATE_CPU (sd, i))) 141a5a4af3bSchristos = print_m32r_misc_cpu; 142a5a4af3bSchristos } 143a5a4af3bSchristos 144a5a4af3bSchristos return sd; 145a5a4af3bSchristos } 146a5a4af3bSchristos 147a5a4af3bSchristos SIM_RC 148*8b657b07Schristos sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char * const *argv, 149*8b657b07Schristos char * const *env) 150a5a4af3bSchristos { 151a5a4af3bSchristos SIM_CPU *current_cpu = STATE_CPU (sd, 0); 152*8b657b07Schristos host_callback *cb = STATE_CALLBACK (sd); 153a5a4af3bSchristos SIM_ADDR addr; 154a5a4af3bSchristos 155a5a4af3bSchristos if (abfd != NULL) 156a5a4af3bSchristos addr = bfd_get_start_address (abfd); 157a5a4af3bSchristos else 158a5a4af3bSchristos addr = 0; 159a5a4af3bSchristos sim_pc_set (current_cpu, addr); 160a5a4af3bSchristos 161*8b657b07Schristos if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT) 162*8b657b07Schristos { 163a5a4af3bSchristos m32rbf_h_cr_set (current_cpu, 164a5a4af3bSchristos m32r_decode_gdb_ctrl_regnum(SPI_REGNUM), 0x1f00000); 165a5a4af3bSchristos m32rbf_h_cr_set (current_cpu, 166a5a4af3bSchristos m32r_decode_gdb_ctrl_regnum(SPU_REGNUM), 0x1f00000); 167*8b657b07Schristos } 168a5a4af3bSchristos 169e5cb852cSchristos /* Standalone mode (i.e. `run`) will take care of the argv for us in 170e5cb852cSchristos sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim' 171e5cb852cSchristos with `gdb`), we need to handle it because the user can change the 172e5cb852cSchristos argv on the fly via gdb's 'run'. */ 173e5cb852cSchristos if (STATE_PROG_ARGV (sd) != argv) 174e5cb852cSchristos { 175e5cb852cSchristos freeargv (STATE_PROG_ARGV (sd)); 176e5cb852cSchristos STATE_PROG_ARGV (sd) = dupargv (argv); 177e5cb852cSchristos } 178a5a4af3bSchristos 179*8b657b07Schristos if (STATE_PROG_ENVP (sd) != env) 180*8b657b07Schristos { 181*8b657b07Schristos freeargv (STATE_PROG_ENVP (sd)); 182*8b657b07Schristos STATE_PROG_ENVP (sd) = dupargv (env); 183*8b657b07Schristos } 184*8b657b07Schristos 185*8b657b07Schristos cb->argv = STATE_PROG_ARGV (sd); 186*8b657b07Schristos cb->envp = STATE_PROG_ENVP (sd); 187*8b657b07Schristos 188a5a4af3bSchristos return SIM_RC_OK; 189a5a4af3bSchristos } 190a5a4af3bSchristos 191a5a4af3bSchristos /* PROFILE_CPU_CALLBACK */ 192a5a4af3bSchristos 193a5a4af3bSchristos static void 194a5a4af3bSchristos print_m32r_misc_cpu (SIM_CPU *cpu, int verbose) 195a5a4af3bSchristos { 196a5a4af3bSchristos SIM_DESC sd = CPU_STATE (cpu); 197a5a4af3bSchristos char buf[20]; 198a5a4af3bSchristos 199a5a4af3bSchristos if (CPU_PROFILE_FLAGS (cpu) [PROFILE_INSN_IDX]) 200a5a4af3bSchristos { 201a5a4af3bSchristos sim_io_printf (sd, "Miscellaneous Statistics\n\n"); 202a5a4af3bSchristos sim_io_printf (sd, " %-*s %s\n\n", 203a5a4af3bSchristos PROFILE_LABEL_WIDTH, "Fill nops:", 204a5a4af3bSchristos sim_add_commas (buf, sizeof (buf), 205a5a4af3bSchristos CPU_M32R_MISC_PROFILE (cpu)->fillnop_count)); 206a5a4af3bSchristos if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32rx) 207a5a4af3bSchristos sim_io_printf (sd, " %-*s %s\n\n", 208a5a4af3bSchristos PROFILE_LABEL_WIDTH, "Parallel insns:", 209a5a4af3bSchristos sim_add_commas (buf, sizeof (buf), 210a5a4af3bSchristos CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); 211a5a4af3bSchristos if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32r2) 212a5a4af3bSchristos sim_io_printf (sd, " %-*s %s\n\n", 213a5a4af3bSchristos PROFILE_LABEL_WIDTH, "Parallel insns:", 214a5a4af3bSchristos sim_add_commas (buf, sizeof (buf), 215a5a4af3bSchristos CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); 216a5a4af3bSchristos } 217a5a4af3bSchristos } 218