14e98e3e1Schristos /* Main simulator entry points specific to the M32R. 2*05fa0856Schristos Copyright (C) 1996-2024 Free Software Foundation, Inc. 34e98e3e1Schristos Contributed by Cygnus Support. 44e98e3e1Schristos 54e98e3e1Schristos This file is part of GDB, the GNU debugger. 64e98e3e1Schristos 74e98e3e1Schristos This program is free software; you can redistribute it and/or modify 84e98e3e1Schristos it under the terms of the GNU General Public License as published by 94e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or 104e98e3e1Schristos (at your option) any later version. 114e98e3e1Schristos 124e98e3e1Schristos This program is distributed in the hope that it will be useful, 134e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 144e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 154e98e3e1Schristos GNU General Public License for more details. 164e98e3e1Schristos 174e98e3e1Schristos You should have received a copy of the GNU General Public License 184e98e3e1Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 194e98e3e1Schristos 204b169a6bSchristos /* This must come before any other includes. */ 214b169a6bSchristos #include "defs.h" 224b169a6bSchristos 234b169a6bSchristos #include <string.h> 244b169a6bSchristos #include <stdlib.h> 254b169a6bSchristos 264b169a6bSchristos #include "sim/callback.h" 274e98e3e1Schristos #include "sim-main.h" 28*05fa0856Schristos #include "sim-hw.h" 294e98e3e1Schristos #include "sim-options.h" 304e98e3e1Schristos #include "libiberty.h" 314e98e3e1Schristos #include "bfd.h" 324e98e3e1Schristos 33*05fa0856Schristos #include "m32r-sim.h" 34ba340e45Schristos #include "dv-m32r_uart.h" 35ba340e45Schristos 364b169a6bSchristos #define M32R_DEFAULT_MEM_SIZE 0x2000000 /* 32M */ 374b169a6bSchristos 384e98e3e1Schristos static void free_state (SIM_DESC); 39*05fa0856Schristos static void print_m32r_misc_cpu (SIM_CPU *cpu, bool verbose); 404e98e3e1Schristos 414e98e3e1Schristos /* Cover function of sim_state_free to free the cpu buffers as well. */ 424e98e3e1Schristos 434e98e3e1Schristos static void 444e98e3e1Schristos free_state (SIM_DESC sd) 454e98e3e1Schristos { 464e98e3e1Schristos if (STATE_MODULES (sd) != NULL) 474e98e3e1Schristos sim_module_uninstall (sd); 484e98e3e1Schristos sim_cpu_free_all (sd); 494e98e3e1Schristos sim_state_free (sd); 504e98e3e1Schristos } 514e98e3e1Schristos 524b169a6bSchristos extern const SIM_MACH * const m32r_sim_machs[]; 534b169a6bSchristos 544e98e3e1Schristos /* Create an instance of the simulator. */ 554e98e3e1Schristos 564e98e3e1Schristos SIM_DESC 574b169a6bSchristos sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd, 584b169a6bSchristos char * const *argv) 594e98e3e1Schristos { 604e98e3e1Schristos SIM_DESC sd = sim_state_alloc (kind, callback); 614e98e3e1Schristos char c; 624e98e3e1Schristos int i; 634e98e3e1Schristos 644b169a6bSchristos /* Set default options before parsing user options. */ 654b169a6bSchristos STATE_MACHS (sd) = m32r_sim_machs; 664b169a6bSchristos STATE_MODEL_NAME (sd) = "m32r/d"; 674b169a6bSchristos current_alignment = STRICT_ALIGNMENT; 684b169a6bSchristos current_target_byte_order = BFD_ENDIAN_BIG; 694b169a6bSchristos 704e98e3e1Schristos /* The cpu data is kept in a separately allocated chunk of memory. */ 71*05fa0856Schristos if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct m32r_sim_cpu)) 72*05fa0856Schristos != SIM_RC_OK) 734e98e3e1Schristos { 744e98e3e1Schristos free_state (sd); 754e98e3e1Schristos return 0; 764e98e3e1Schristos } 774e98e3e1Schristos 784e98e3e1Schristos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 794e98e3e1Schristos { 804e98e3e1Schristos free_state (sd); 814e98e3e1Schristos return 0; 824e98e3e1Schristos } 834e98e3e1Schristos 84ba340e45Schristos /* The parser will print an error message for us, so we silently return. */ 854e98e3e1Schristos if (sim_parse_args (sd, argv) != SIM_RC_OK) 864e98e3e1Schristos { 874e98e3e1Schristos free_state (sd); 884e98e3e1Schristos return 0; 894e98e3e1Schristos } 904e98e3e1Schristos 914e98e3e1Schristos /* Allocate a handler for the control registers and other devices 924e98e3e1Schristos if no memory for that range has been allocated by the user. 934e98e3e1Schristos All are allocated in one chunk to keep things from being 94ba340e45Schristos unnecessarily complicated. 95ba340e45Schristos TODO: Move these to the sim-model framework. */ 96ba340e45Schristos sim_hw_parse (sd, "/core/%s/reg %#x %i", "m32r_uart", UART_BASE_ADDR, 0x100); 97ba340e45Schristos sim_hw_parse (sd, "/core/%s/reg %#x %i", "m32r_cache", 0xfffffff0, 0x10); 984e98e3e1Schristos 994e98e3e1Schristos /* Allocate core managed memory if none specified by user. 1004e98e3e1Schristos Use address 4 here in case the user wanted address 0 unmapped. */ 1014e98e3e1Schristos if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0) 1024e98e3e1Schristos sim_do_commandf (sd, "memory region 0,0x%x", M32R_DEFAULT_MEM_SIZE); 1034e98e3e1Schristos 1044e98e3e1Schristos /* check for/establish the reference program image */ 1054b169a6bSchristos if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 1064e98e3e1Schristos { 1074e98e3e1Schristos free_state (sd); 1084e98e3e1Schristos return 0; 1094e98e3e1Schristos } 1104e98e3e1Schristos 1114e98e3e1Schristos /* Establish any remaining configuration options. */ 1124e98e3e1Schristos if (sim_config (sd) != SIM_RC_OK) 1134e98e3e1Schristos { 1144e98e3e1Schristos free_state (sd); 1154e98e3e1Schristos return 0; 1164e98e3e1Schristos } 1174e98e3e1Schristos 1184e98e3e1Schristos if (sim_post_argv_init (sd) != SIM_RC_OK) 1194e98e3e1Schristos { 1204e98e3e1Schristos free_state (sd); 1214e98e3e1Schristos return 0; 1224e98e3e1Schristos } 1234e98e3e1Schristos 1244e98e3e1Schristos /* Open a copy of the cpu descriptor table. */ 1254e98e3e1Schristos { 1264e98e3e1Schristos CGEN_CPU_DESC cd = m32r_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name, 1274e98e3e1Schristos CGEN_ENDIAN_BIG); 1284e98e3e1Schristos for (i = 0; i < MAX_NR_PROCESSORS; ++i) 1294e98e3e1Schristos { 1304e98e3e1Schristos SIM_CPU *cpu = STATE_CPU (sd, i); 1314e98e3e1Schristos CPU_CPU_DESC (cpu) = cd; 1324e98e3e1Schristos CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn; 1334e98e3e1Schristos } 1344e98e3e1Schristos m32r_cgen_init_dis (cd); 1354e98e3e1Schristos } 1364e98e3e1Schristos 137*05fa0856Schristos for (i = 0; i < MAX_NR_PROCESSORS; ++i) 1384e98e3e1Schristos { 1394e98e3e1Schristos /* Only needed for profiling, but the structure member is small. */ 1404e98e3e1Schristos memset (CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)), 0, 1414e98e3e1Schristos sizeof (* CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)))); 1424e98e3e1Schristos /* Hook in callback for reporting these stats */ 1434e98e3e1Schristos PROFILE_INFO_CPU_CALLBACK (CPU_PROFILE_DATA (STATE_CPU (sd, i))) 1444e98e3e1Schristos = print_m32r_misc_cpu; 1454e98e3e1Schristos } 1464e98e3e1Schristos 1474e98e3e1Schristos return sd; 1484e98e3e1Schristos } 1494e98e3e1Schristos 1504e98e3e1Schristos SIM_RC 1514b169a6bSchristos sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char * const *argv, 1524b169a6bSchristos char * const *env) 1534e98e3e1Schristos { 1544e98e3e1Schristos SIM_CPU *current_cpu = STATE_CPU (sd, 0); 1554b169a6bSchristos host_callback *cb = STATE_CALLBACK (sd); 156*05fa0856Schristos bfd_vma addr; 1574e98e3e1Schristos 1584e98e3e1Schristos if (abfd != NULL) 1594e98e3e1Schristos addr = bfd_get_start_address (abfd); 1604e98e3e1Schristos else 1614e98e3e1Schristos addr = 0; 1624e98e3e1Schristos sim_pc_set (current_cpu, addr); 1634e98e3e1Schristos 1644b169a6bSchristos if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT) 1654b169a6bSchristos { 1664e98e3e1Schristos m32rbf_h_cr_set (current_cpu, 1674e98e3e1Schristos m32r_decode_gdb_ctrl_regnum(SPI_REGNUM), 0x1f00000); 1684e98e3e1Schristos m32rbf_h_cr_set (current_cpu, 1694e98e3e1Schristos m32r_decode_gdb_ctrl_regnum(SPU_REGNUM), 0x1f00000); 1704b169a6bSchristos } 1714e98e3e1Schristos 172ba340e45Schristos /* Standalone mode (i.e. `run`) will take care of the argv for us in 173ba340e45Schristos sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim' 174ba340e45Schristos with `gdb`), we need to handle it because the user can change the 175ba340e45Schristos argv on the fly via gdb's 'run'. */ 176ba340e45Schristos if (STATE_PROG_ARGV (sd) != argv) 177ba340e45Schristos { 178ba340e45Schristos freeargv (STATE_PROG_ARGV (sd)); 179ba340e45Schristos STATE_PROG_ARGV (sd) = dupargv (argv); 180ba340e45Schristos } 1814e98e3e1Schristos 1824b169a6bSchristos if (STATE_PROG_ENVP (sd) != env) 1834b169a6bSchristos { 1844b169a6bSchristos freeargv (STATE_PROG_ENVP (sd)); 1854b169a6bSchristos STATE_PROG_ENVP (sd) = dupargv (env); 1864b169a6bSchristos } 1874b169a6bSchristos 1884b169a6bSchristos cb->argv = STATE_PROG_ARGV (sd); 1894b169a6bSchristos cb->envp = STATE_PROG_ENVP (sd); 1904b169a6bSchristos 1914e98e3e1Schristos return SIM_RC_OK; 1924e98e3e1Schristos } 1934e98e3e1Schristos 1944e98e3e1Schristos /* PROFILE_CPU_CALLBACK */ 1954e98e3e1Schristos 1964e98e3e1Schristos static void 197*05fa0856Schristos print_m32r_misc_cpu (SIM_CPU *cpu, bool verbose) 1984e98e3e1Schristos { 1994e98e3e1Schristos SIM_DESC sd = CPU_STATE (cpu); 2004e98e3e1Schristos char buf[20]; 2014e98e3e1Schristos 2024e98e3e1Schristos if (CPU_PROFILE_FLAGS (cpu) [PROFILE_INSN_IDX]) 2034e98e3e1Schristos { 2044e98e3e1Schristos sim_io_printf (sd, "Miscellaneous Statistics\n\n"); 2054e98e3e1Schristos sim_io_printf (sd, " %-*s %s\n\n", 2064e98e3e1Schristos PROFILE_LABEL_WIDTH, "Fill nops:", 2074e98e3e1Schristos sim_add_commas (buf, sizeof (buf), 2084e98e3e1Schristos CPU_M32R_MISC_PROFILE (cpu)->fillnop_count)); 2094e98e3e1Schristos if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32rx) 2104e98e3e1Schristos sim_io_printf (sd, " %-*s %s\n\n", 2114e98e3e1Schristos PROFILE_LABEL_WIDTH, "Parallel insns:", 2124e98e3e1Schristos sim_add_commas (buf, sizeof (buf), 2134e98e3e1Schristos CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); 2144e98e3e1Schristos if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32r2) 2154e98e3e1Schristos sim_io_printf (sd, " %-*s %s\n\n", 2164e98e3e1Schristos PROFILE_LABEL_WIDTH, "Parallel insns:", 2174e98e3e1Schristos sim_add_commas (buf, sizeof (buf), 2184e98e3e1Schristos CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); 2194e98e3e1Schristos } 2204e98e3e1Schristos } 221