xref: /netbsd-src/external/gpl3/gdb/dist/sim/frv/sim-if.c (revision 28bcf0b924ec476f57aeda79eff0c1a07cb62e5f)
1 /* Main simulator entry points specific to the FRV.
2    Copyright (C) 1998-2024 Free Software Foundation, Inc.
3    Contributed by Red Hat.
4 
5 This file is part of the GNU simulators.
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 /* This must come before any other includes.  */
21 #include "defs.h"
22 
23 #include <stdlib.h>
24 
25 #include "sim/callback.h"
26 
27 #define WANT_CPU
28 #define WANT_CPU_FRVBF
29 #include "sim-main.h"
30 #include "sim-options.h"
31 #include "libiberty.h"
32 #include "bfd.h"
33 #include "bfd/elf-bfd.h"
34 
35 static void free_state (SIM_DESC);
36 
37 /* Cover function of sim_state_free to free the cpu buffers as well.  */
38 
39 static void
40 free_state (SIM_DESC sd)
41 {
42   if (STATE_MODULES (sd) != NULL)
43     sim_module_uninstall (sd);
44   sim_cpu_free_all (sd);
45   sim_state_free (sd);
46 }
47 
48 extern const SIM_MACH * const frv_sim_machs[];
49 
50 /* Create an instance of the simulator.  */
51 
52 SIM_DESC
53 sim_open (SIM_OPEN_KIND kind, host_callback *callback, bfd *abfd,
54 	  char * const *argv)
55 {
56   char c;
57   int i;
58   unsigned long elf_flags = 0;
59   SIM_DESC sd = sim_state_alloc (kind, callback);
60 
61   /* Set default options before parsing user options.  */
62   STATE_MACHS (sd) = frv_sim_machs;
63   STATE_MODEL_NAME (sd) = "fr500";
64   current_alignment = STRICT_ALIGNMENT;
65   current_target_byte_order = BFD_ENDIAN_BIG;
66 
67   /* The cpu data is kept in a separately allocated chunk of memory.  */
68   if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct frv_sim_cpu)) != SIM_RC_OK)
69     {
70       free_state (sd);
71       return 0;
72     }
73 
74   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
75     {
76       free_state (sd);
77       return 0;
78     }
79 
80   /* These options override any module options.
81      Obviously ambiguity should be avoided, however the caller may wish to
82      augment the meaning of an option.  */
83   sim_add_option_table (sd, NULL, frv_options);
84 
85   /* The parser will print an error message for us, so we silently return.  */
86   if (sim_parse_args (sd, argv) != SIM_RC_OK)
87     {
88       free_state (sd);
89       return 0;
90     }
91 
92   /* Allocate core managed memory if none specified by user.
93      Use address 4 here in case the user wanted address 0 unmapped.  */
94   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
95     sim_do_commandf (sd, "memory region 0,0x%x", FRV_DEFAULT_MEM_SIZE);
96 
97   /* check for/establish the reference program image */
98   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
99     {
100       free_state (sd);
101       return 0;
102     }
103 
104   /* set machine and architecture correctly instead of defaulting to frv */
105   {
106     bfd *prog_bfd = STATE_PROG_BFD (sd);
107     if (prog_bfd != NULL)
108       {
109 	const struct elf_backend_data *backend_data;
110 
111 	if (bfd_get_arch (prog_bfd) != bfd_arch_frv)
112 	  {
113 	    sim_io_eprintf (sd, "%s: \"%s\" is not a FRV object file\n",
114 			    STATE_MY_NAME (sd),
115 			    bfd_get_filename (prog_bfd));
116 	    free_state (sd);
117 	    return 0;
118 	  }
119 
120 	backend_data = get_elf_backend_data (prog_bfd);
121 
122 	if (backend_data != NULL)
123 	  backend_data->elf_backend_object_p (prog_bfd);
124 
125 	elf_flags = elf_elfheader (prog_bfd)->e_flags;
126       }
127   }
128 
129   /* Establish any remaining configuration options.  */
130   if (sim_config (sd) != SIM_RC_OK)
131     {
132       free_state (sd);
133       return 0;
134     }
135 
136   if (sim_post_argv_init (sd) != SIM_RC_OK)
137     {
138       free_state (sd);
139       return 0;
140     }
141 
142   /* Open a copy of the cpu descriptor table.  */
143   {
144     CGEN_CPU_DESC cd = frv_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
145 					     CGEN_ENDIAN_BIG);
146     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
147       {
148 	SIM_CPU *cpu = STATE_CPU (sd, i);
149 	CPU_CPU_DESC (cpu) = cd;
150 	CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
151 	CPU_ELF_FLAGS (cpu) = elf_flags;
152       }
153     frv_cgen_init_dis (cd);
154   }
155 
156   /* CPU specific initialization.  */
157   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
158     {
159       SIM_CPU* cpu = STATE_CPU (sd, i);
160       frv_initialize (cpu, sd);
161     }
162 
163   return sd;
164 }
165 
166 void
167 frv_sim_close (SIM_DESC sd, int quitting)
168 {
169   int i;
170   /* Terminate cache support.  */
171   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
172     {
173       SIM_CPU* cpu = STATE_CPU (sd, i);
174       frv_cache_term (CPU_INSN_CACHE (cpu));
175       frv_cache_term (CPU_DATA_CACHE (cpu));
176     }
177 }
178 
179 SIM_RC
180 sim_create_inferior (SIM_DESC sd, bfd *abfd, char * const *argv,
181 		     char * const *env)
182 {
183   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
184   host_callback *cb = STATE_CALLBACK (sd);
185   bfd_vma addr;
186 
187   if (abfd != NULL)
188     addr = bfd_get_start_address (abfd);
189   else
190     addr = 0;
191   sim_pc_set (current_cpu, addr);
192 
193   /* Standalone mode (i.e. `run`) will take care of the argv for us in
194      sim_open() -> sim_parse_args().  But in debug mode (i.e. 'target sim'
195      with `gdb`), we need to handle it because the user can change the
196      argv on the fly via gdb's 'run'.  */
197   if (STATE_PROG_ARGV (sd) != argv)
198     {
199       freeargv (STATE_PROG_ARGV (sd));
200       STATE_PROG_ARGV (sd) = dupargv (argv);
201     }
202 
203   if (STATE_PROG_ENVP (sd) != env)
204     {
205       freeargv (STATE_PROG_ENVP (sd));
206       STATE_PROG_ENVP (sd) = dupargv (env);
207     }
208 
209   cb->argv = STATE_PROG_ARGV (sd);
210   cb->envp = STATE_PROG_ENVP (sd);
211 
212   return SIM_RC_OK;
213 }
214