xref: /netbsd-src/external/gpl3/gdb/dist/sim/or1k/sim-if.c (revision 0388e998654430ce19a2917dec7ff0950bcf2e1c)
1 /* Main simulator entry points specific to the OR1K.
2    Copyright (C) 2017-2024 Free Software Foundation, Inc.
3 
4    This file is part of GDB, the GNU debugger.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 /* This must come before any other includes.  */
20 #include "defs.h"
21 
22 #include "sim-main.h"
23 #include "sim-options.h"
24 #include "libiberty.h"
25 #include "bfd.h"
26 
27 #include <string.h>
28 #include <stdlib.h>
29 
30 static void free_state (SIM_DESC);
31 
32 
33 /* Cover function of sim_state_free to free the cpu buffers as well.  */
34 
35 static void
36 free_state (SIM_DESC sd)
37 {
38   if (STATE_MODULES (sd) != NULL)
39     sim_module_uninstall (sd);
40   sim_cpu_free_all (sd);
41   sim_state_free (sd);
42 }
43 
44 /* Defaults for user passed arguments.  */
45 static const USI or1k_default_vr = 0x0;
46 static const USI or1k_default_upr = 0x0
47   | SPR_FIELD_MASK_SYS_UPR_UP;
48 static const USI or1k_default_cpucfgr = 0x0
49   | SPR_FIELD_MASK_SYS_CPUCFGR_OB32S
50   | SPR_FIELD_MASK_SYS_CPUCFGR_OF32S;
51 
52 static UWI or1k_upr;
53 static UWI or1k_vr;
54 static UWI or1k_cpucfgr;
55 
56 enum
57 {
58   OPTION_OR1K_VR,
59   OPTION_OR1K_UPR,
60   OPTION_OR1K_CPUCFGR = OPTION_START,
61 };
62 
63 /* Setup help and handlers for the user defined arguments.  */
64 DECLARE_OPTION_HANDLER (or1k_option_handler);
65 
66 static const OPTION or1k_options[] = {
67   {{"or1k-cpucfgr", required_argument, NULL, OPTION_OR1K_CPUCFGR},
68    '\0', "INTEGER|default", "Set simulator CPUCFGR value",
69    or1k_option_handler},
70   {{"or1k-vr", required_argument, NULL, OPTION_OR1K_VR},
71    '\0', "INTEGER|default", "Set simulator VR value",
72    or1k_option_handler},
73   {{"or1k-upr", required_argument, NULL, OPTION_OR1K_UPR},
74    '\0', "INTEGER|default", "Set simulator UPR value",
75    or1k_option_handler},
76   {{NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL}
77 };
78 
79 /* Handler for parsing user defined arguments.  Currently we support
80    configuring some of the CPU implementation specific registers including
81    the Version Register (VR), the Unit Present Register (UPR) and the CPU
82    Configuration Register (CPUCFGR).  */
83 SIM_RC
84 or1k_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg,
85 		     int is_command)
86 {
87   switch (opt)
88     {
89     case OPTION_OR1K_VR:
90       if (strcmp ("default", arg) == 0)
91 	or1k_vr = or1k_default_vr;
92       else
93 	{
94 	  unsigned long long n;
95 	  char *endptr;
96 
97 	  n = strtoull (arg, &endptr, 0);
98 	  if (*arg != '\0' && *endptr == '\0')
99 	    or1k_vr = n;
100 	  else
101 	    return SIM_RC_FAIL;
102 	}
103       return SIM_RC_OK;
104 
105     case OPTION_OR1K_UPR:
106       if (strcmp ("default", arg) == 0)
107 	or1k_upr = or1k_default_upr;
108       else
109 	{
110 	  unsigned long long n;
111 	  char *endptr;
112 
113 	  n = strtoull (arg, &endptr, 0);
114 	  if (*arg != '\0' && *endptr == '\0')
115 	    or1k_upr = n;
116 	  else
117 	    {
118 	      sim_io_eprintf
119 		(sd, "invalid argument to option --or1k-upr: `%s'\n", arg);
120 	      return SIM_RC_FAIL;
121 	    }
122 	}
123       return SIM_RC_OK;
124 
125     case OPTION_OR1K_CPUCFGR:
126       if (strcmp ("default", arg) == 0)
127 	or1k_cpucfgr = or1k_default_cpucfgr;
128       else
129 	{
130 	  unsigned long long n;
131 	  char *endptr;
132 
133 	  n = strtoull (arg, &endptr, 0);
134 	  if (*arg != '\0' && *endptr == '\0')
135 	    or1k_cpucfgr = n;
136 	  else
137 	    {
138 	      sim_io_eprintf
139 		(sd, "invalid argument to option --or1k-cpucfgr: `%s'\n", arg);
140 	      return SIM_RC_FAIL;
141 	    }
142 	}
143       return SIM_RC_OK;
144 
145     default:
146       sim_io_eprintf (sd, "Unknown or1k option %d\n", opt);
147       return SIM_RC_FAIL;
148     }
149 
150   return SIM_RC_FAIL;
151 }
152 
153 extern const SIM_MACH * const or1k_sim_machs[];
154 
155 /* Create an instance of the simulator.  */
156 
157 SIM_DESC
158 sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
159 	  char * const *argv)
160 {
161   SIM_DESC sd = sim_state_alloc (kind, callback);
162   char c;
163   int i;
164 
165   /* Set default options before parsing user options.  */
166   STATE_MACHS (sd) = or1k_sim_machs;
167   STATE_MODEL_NAME (sd) = "or1200";
168   current_target_byte_order = BFD_ENDIAN_BIG;
169 
170   /* The cpu data is kept in a separately allocated chunk of memory.  */
171   if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct or1k_sim_cpu))
172       != SIM_RC_OK)
173     {
174       free_state (sd);
175       return 0;
176     }
177 
178   /* Perform initial sim setups.  */
179   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
180     {
181       free_state (sd);
182       return 0;
183     }
184 
185   or1k_upr = or1k_default_upr;
186   or1k_vr = or1k_default_vr;
187   or1k_cpucfgr = or1k_default_cpucfgr;
188   sim_add_option_table (sd, NULL, or1k_options);
189 
190   /* Parse the user passed arguments.  */
191   if (sim_parse_args (sd, argv) != SIM_RC_OK)
192     {
193       free_state (sd);
194       return 0;
195     }
196 
197   /* Allocate core managed memory if none specified by user.
198      Use address 4 here in case the user wanted address 0 unmapped.  */
199   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
200     {
201       sim_do_commandf (sd, "memory region 0,0x%x", OR1K_DEFAULT_MEM_SIZE);
202     }
203 
204   /* Check for/establish the reference program image.  */
205   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
206     {
207       free_state (sd);
208       return 0;
209     }
210 
211   /* Establish any remaining configuration options.  */
212   if (sim_config (sd) != SIM_RC_OK)
213     {
214       free_state (sd);
215       return 0;
216     }
217 
218   if (sim_post_argv_init (sd) != SIM_RC_OK)
219     {
220       free_state (sd);
221       return 0;
222     }
223 
224   /* Make sure delay slot mode is consistent with the loaded binary.  */
225   if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_or1knd)
226     or1k_cpucfgr |= SPR_FIELD_MASK_SYS_CPUCFGR_ND;
227   else
228     or1k_cpucfgr &= ~SPR_FIELD_MASK_SYS_CPUCFGR_ND;
229 
230   /* Open a copy of the cpu descriptor table and initialize the
231      disassembler.  These initialization functions are generated by CGEN
232      using the binutils scheme cpu description files.  */
233   {
234     CGEN_CPU_DESC cd =
235       or1k_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
236 			    CGEN_ENDIAN_BIG);
237     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
238       {
239 	SIM_CPU *cpu = STATE_CPU (sd, i);
240 	CPU_CPU_DESC (cpu) = cd;
241 	CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
242       }
243     or1k_cgen_init_dis (cd);
244   }
245 
246   /* Do some final OpenRISC sim specific initializations.  */
247   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
248     {
249       SIM_CPU *cpu = STATE_CPU (sd, i);
250       /* Only needed for profiling, but the structure member is small.  */
251       memset (CPU_OR1K_MISC_PROFILE (cpu), 0,
252 	      sizeof (*CPU_OR1K_MISC_PROFILE (cpu)));
253 
254       or1k_cpu_init (sd, cpu, or1k_vr, or1k_upr, or1k_cpucfgr);
255     }
256 
257   return sd;
258 }
259 
260 
261 SIM_RC
262 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
263 		     char * const *argv, char * const *envp)
264 {
265   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
266   bfd_vma addr;
267 
268   if (abfd != NULL)
269     addr = bfd_get_start_address (abfd);
270   else
271     addr = 0;
272   sim_pc_set (current_cpu, addr);
273 
274   return SIM_RC_OK;
275 }
276