xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/m32r/sim-if.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
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