xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/or1k/sim-if.c (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1 /* Main simulator entry points specific to the OR1K.
2    Copyright (C) 2017-2023 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 (sd, 1) != SIM_RC_OK)
172     {
173       free_state (sd);
174       return 0;
175     }
176 
177   /* Perform initial sim setups.  */
178   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
179     {
180       free_state (sd);
181       return 0;
182     }
183 
184   or1k_upr = or1k_default_upr;
185   or1k_vr = or1k_default_vr;
186   or1k_cpucfgr = or1k_default_cpucfgr;
187   sim_add_option_table (sd, NULL, or1k_options);
188 
189   /* Parse the user passed arguments.  */
190   if (sim_parse_args (sd, argv) != SIM_RC_OK)
191     {
192       free_state (sd);
193       return 0;
194     }
195 
196   /* Allocate core managed memory if none specified by user.
197      Use address 4 here in case the user wanted address 0 unmapped.  */
198   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
199     {
200       sim_do_commandf (sd, "memory region 0,0x%x", OR1K_DEFAULT_MEM_SIZE);
201     }
202 
203   /* Check for/establish the reference program image.  */
204   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
205     {
206       free_state (sd);
207       return 0;
208     }
209 
210   /* Establish any remaining configuration options.  */
211   if (sim_config (sd) != SIM_RC_OK)
212     {
213       free_state (sd);
214       return 0;
215     }
216 
217   if (sim_post_argv_init (sd) != SIM_RC_OK)
218     {
219       free_state (sd);
220       return 0;
221     }
222 
223   /* Make sure delay slot mode is consistent with the loaded binary.  */
224   if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_or1knd)
225     or1k_cpucfgr |= SPR_FIELD_MASK_SYS_CPUCFGR_ND;
226   else
227     or1k_cpucfgr &= ~SPR_FIELD_MASK_SYS_CPUCFGR_ND;
228 
229   /* Open a copy of the cpu descriptor table and initialize the
230      disassembler.  These initialization functions are generated by CGEN
231      using the binutils scheme cpu description files.  */
232   {
233     CGEN_CPU_DESC cd =
234       or1k_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
235 			    CGEN_ENDIAN_BIG);
236     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
237       {
238 	SIM_CPU *cpu = STATE_CPU (sd, i);
239 	CPU_CPU_DESC (cpu) = cd;
240 	CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
241       }
242     or1k_cgen_init_dis (cd);
243   }
244 
245   /* Do some final OpenRISC sim specific initializations.  */
246   for (c = 0; c < MAX_NR_PROCESSORS; ++c)
247     {
248       SIM_CPU *cpu = STATE_CPU (sd, i);
249       /* Only needed for profiling, but the structure member is small.  */
250       memset (CPU_OR1K_MISC_PROFILE (cpu), 0,
251 	      sizeof (*CPU_OR1K_MISC_PROFILE (cpu)));
252 
253       or1k_cpu_init (sd, cpu, or1k_vr, or1k_upr, or1k_cpucfgr);
254     }
255 
256   return sd;
257 }
258 
259 
260 SIM_RC
261 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
262 		     char * const *argv, char * const *envp)
263 {
264   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
265   SIM_ADDR addr;
266 
267   if (abfd != NULL)
268     addr = bfd_get_start_address (abfd);
269   else
270     addr = 0;
271   sim_pc_set (current_cpu, addr);
272 
273   return SIM_RC_OK;
274 }
275