xref: /netbsd-src/external/gpl3/gdb/dist/sim/or1k/sim-if.c (revision 0388e998654430ce19a2917dec7ff0950bcf2e1c)
14559860eSchristos /* Main simulator entry points specific to the OR1K.
2*0388e998Schristos    Copyright (C) 2017-2024 Free Software Foundation, Inc.
34559860eSchristos 
44559860eSchristos    This file is part of GDB, the GNU debugger.
54559860eSchristos 
64559860eSchristos    This program is free software; you can redistribute it and/or modify
74559860eSchristos    it under the terms of the GNU General Public License as published by
84559860eSchristos    the Free Software Foundation; either version 3 of the License, or
94559860eSchristos    (at your option) any later version.
104559860eSchristos 
114559860eSchristos    This program is distributed in the hope that it will be useful,
124559860eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
134559860eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144559860eSchristos    GNU General Public License for more details.
154559860eSchristos 
164559860eSchristos    You should have received a copy of the GNU General Public License
174559860eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
184559860eSchristos 
194b169a6bSchristos /* This must come before any other includes.  */
204b169a6bSchristos #include "defs.h"
214b169a6bSchristos 
224559860eSchristos #include "sim-main.h"
234559860eSchristos #include "sim-options.h"
244559860eSchristos #include "libiberty.h"
254559860eSchristos #include "bfd.h"
264559860eSchristos 
274559860eSchristos #include <string.h>
284559860eSchristos #include <stdlib.h>
294559860eSchristos 
304559860eSchristos static void free_state (SIM_DESC);
314559860eSchristos 
324559860eSchristos 
334559860eSchristos /* Cover function of sim_state_free to free the cpu buffers as well.  */
344559860eSchristos 
354559860eSchristos static void
364559860eSchristos free_state (SIM_DESC sd)
374559860eSchristos {
384559860eSchristos   if (STATE_MODULES (sd) != NULL)
394559860eSchristos     sim_module_uninstall (sd);
404559860eSchristos   sim_cpu_free_all (sd);
414559860eSchristos   sim_state_free (sd);
424559860eSchristos }
434559860eSchristos 
444559860eSchristos /* Defaults for user passed arguments.  */
454559860eSchristos static const USI or1k_default_vr = 0x0;
464559860eSchristos static const USI or1k_default_upr = 0x0
474559860eSchristos   | SPR_FIELD_MASK_SYS_UPR_UP;
484559860eSchristos static const USI or1k_default_cpucfgr = 0x0
494559860eSchristos   | SPR_FIELD_MASK_SYS_CPUCFGR_OB32S
504559860eSchristos   | SPR_FIELD_MASK_SYS_CPUCFGR_OF32S;
514559860eSchristos 
524559860eSchristos static UWI or1k_upr;
534559860eSchristos static UWI or1k_vr;
544559860eSchristos static UWI or1k_cpucfgr;
554559860eSchristos 
564559860eSchristos enum
574559860eSchristos {
584559860eSchristos   OPTION_OR1K_VR,
594559860eSchristos   OPTION_OR1K_UPR,
604559860eSchristos   OPTION_OR1K_CPUCFGR = OPTION_START,
614559860eSchristos };
624559860eSchristos 
634559860eSchristos /* Setup help and handlers for the user defined arguments.  */
644559860eSchristos DECLARE_OPTION_HANDLER (or1k_option_handler);
654559860eSchristos 
664559860eSchristos static const OPTION or1k_options[] = {
674559860eSchristos   {{"or1k-cpucfgr", required_argument, NULL, OPTION_OR1K_CPUCFGR},
684559860eSchristos    '\0', "INTEGER|default", "Set simulator CPUCFGR value",
694559860eSchristos    or1k_option_handler},
704559860eSchristos   {{"or1k-vr", required_argument, NULL, OPTION_OR1K_VR},
714559860eSchristos    '\0', "INTEGER|default", "Set simulator VR value",
724559860eSchristos    or1k_option_handler},
734559860eSchristos   {{"or1k-upr", required_argument, NULL, OPTION_OR1K_UPR},
744559860eSchristos    '\0', "INTEGER|default", "Set simulator UPR value",
754559860eSchristos    or1k_option_handler},
764559860eSchristos   {{NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL}
774559860eSchristos };
784559860eSchristos 
794559860eSchristos /* Handler for parsing user defined arguments.  Currently we support
804559860eSchristos    configuring some of the CPU implementation specific registers including
814559860eSchristos    the Version Register (VR), the Unit Present Register (UPR) and the CPU
824559860eSchristos    Configuration Register (CPUCFGR).  */
834559860eSchristos SIM_RC
844559860eSchristos or1k_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg,
854559860eSchristos 		     int is_command)
864559860eSchristos {
874559860eSchristos   switch (opt)
884559860eSchristos     {
894559860eSchristos     case OPTION_OR1K_VR:
904559860eSchristos       if (strcmp ("default", arg) == 0)
914559860eSchristos 	or1k_vr = or1k_default_vr;
924559860eSchristos       else
934559860eSchristos 	{
944559860eSchristos 	  unsigned long long n;
954559860eSchristos 	  char *endptr;
964559860eSchristos 
974559860eSchristos 	  n = strtoull (arg, &endptr, 0);
984559860eSchristos 	  if (*arg != '\0' && *endptr == '\0')
994559860eSchristos 	    or1k_vr = n;
1004559860eSchristos 	  else
1014559860eSchristos 	    return SIM_RC_FAIL;
1024559860eSchristos 	}
1034559860eSchristos       return SIM_RC_OK;
1044559860eSchristos 
1054559860eSchristos     case OPTION_OR1K_UPR:
1064559860eSchristos       if (strcmp ("default", arg) == 0)
1074559860eSchristos 	or1k_upr = or1k_default_upr;
1084559860eSchristos       else
1094559860eSchristos 	{
1104559860eSchristos 	  unsigned long long n;
1114559860eSchristos 	  char *endptr;
1124559860eSchristos 
1134559860eSchristos 	  n = strtoull (arg, &endptr, 0);
1144559860eSchristos 	  if (*arg != '\0' && *endptr == '\0')
1154559860eSchristos 	    or1k_upr = n;
1164559860eSchristos 	  else
1174559860eSchristos 	    {
1184559860eSchristos 	      sim_io_eprintf
1194559860eSchristos 		(sd, "invalid argument to option --or1k-upr: `%s'\n", arg);
1204559860eSchristos 	      return SIM_RC_FAIL;
1214559860eSchristos 	    }
1224559860eSchristos 	}
1234559860eSchristos       return SIM_RC_OK;
1244559860eSchristos 
1254559860eSchristos     case OPTION_OR1K_CPUCFGR:
1264559860eSchristos       if (strcmp ("default", arg) == 0)
1274559860eSchristos 	or1k_cpucfgr = or1k_default_cpucfgr;
1284559860eSchristos       else
1294559860eSchristos 	{
1304559860eSchristos 	  unsigned long long n;
1314559860eSchristos 	  char *endptr;
1324559860eSchristos 
1334559860eSchristos 	  n = strtoull (arg, &endptr, 0);
1344559860eSchristos 	  if (*arg != '\0' && *endptr == '\0')
1354559860eSchristos 	    or1k_cpucfgr = n;
1364559860eSchristos 	  else
1374559860eSchristos 	    {
1384559860eSchristos 	      sim_io_eprintf
1394559860eSchristos 		(sd, "invalid argument to option --or1k-cpucfgr: `%s'\n", arg);
1404559860eSchristos 	      return SIM_RC_FAIL;
1414559860eSchristos 	    }
1424559860eSchristos 	}
1434559860eSchristos       return SIM_RC_OK;
1444559860eSchristos 
1454559860eSchristos     default:
1464559860eSchristos       sim_io_eprintf (sd, "Unknown or1k option %d\n", opt);
1474559860eSchristos       return SIM_RC_FAIL;
1484559860eSchristos     }
1494559860eSchristos 
1504559860eSchristos   return SIM_RC_FAIL;
1514559860eSchristos }
1524559860eSchristos 
1534b169a6bSchristos extern const SIM_MACH * const or1k_sim_machs[];
1544b169a6bSchristos 
1554559860eSchristos /* Create an instance of the simulator.  */
1564559860eSchristos 
1574559860eSchristos SIM_DESC
1584559860eSchristos sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
1594559860eSchristos 	  char * const *argv)
1604559860eSchristos {
1614559860eSchristos   SIM_DESC sd = sim_state_alloc (kind, callback);
1624559860eSchristos   char c;
1634559860eSchristos   int i;
1644559860eSchristos 
1654b169a6bSchristos   /* Set default options before parsing user options.  */
1664b169a6bSchristos   STATE_MACHS (sd) = or1k_sim_machs;
1674b169a6bSchristos   STATE_MODEL_NAME (sd) = "or1200";
1684b169a6bSchristos   current_target_byte_order = BFD_ENDIAN_BIG;
1694b169a6bSchristos 
1704559860eSchristos   /* The cpu data is kept in a separately allocated chunk of memory.  */
171*0388e998Schristos   if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct or1k_sim_cpu))
172*0388e998Schristos       != SIM_RC_OK)
1734559860eSchristos     {
1744559860eSchristos       free_state (sd);
1754559860eSchristos       return 0;
1764559860eSchristos     }
1774559860eSchristos 
1784559860eSchristos   /* Perform initial sim setups.  */
1794559860eSchristos   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1804559860eSchristos     {
1814559860eSchristos       free_state (sd);
1824559860eSchristos       return 0;
1834559860eSchristos     }
1844559860eSchristos 
1854559860eSchristos   or1k_upr = or1k_default_upr;
1864559860eSchristos   or1k_vr = or1k_default_vr;
1874559860eSchristos   or1k_cpucfgr = or1k_default_cpucfgr;
1884559860eSchristos   sim_add_option_table (sd, NULL, or1k_options);
1894559860eSchristos 
1904559860eSchristos   /* Parse the user passed arguments.  */
1914559860eSchristos   if (sim_parse_args (sd, argv) != SIM_RC_OK)
1924559860eSchristos     {
1934559860eSchristos       free_state (sd);
1944559860eSchristos       return 0;
1954559860eSchristos     }
1964559860eSchristos 
1974559860eSchristos   /* Allocate core managed memory if none specified by user.
1984559860eSchristos      Use address 4 here in case the user wanted address 0 unmapped.  */
1994559860eSchristos   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
2004559860eSchristos     {
2014559860eSchristos       sim_do_commandf (sd, "memory region 0,0x%x", OR1K_DEFAULT_MEM_SIZE);
2024559860eSchristos     }
2034559860eSchristos 
2044559860eSchristos   /* Check for/establish the reference program image.  */
2054b169a6bSchristos   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
2064559860eSchristos     {
2074559860eSchristos       free_state (sd);
2084559860eSchristos       return 0;
2094559860eSchristos     }
2104559860eSchristos 
2114559860eSchristos   /* Establish any remaining configuration options.  */
2124559860eSchristos   if (sim_config (sd) != SIM_RC_OK)
2134559860eSchristos     {
2144559860eSchristos       free_state (sd);
2154559860eSchristos       return 0;
2164559860eSchristos     }
2174559860eSchristos 
2184559860eSchristos   if (sim_post_argv_init (sd) != SIM_RC_OK)
2194559860eSchristos     {
2204559860eSchristos       free_state (sd);
2214559860eSchristos       return 0;
2224559860eSchristos     }
2234559860eSchristos 
2244559860eSchristos   /* Make sure delay slot mode is consistent with the loaded binary.  */
2254559860eSchristos   if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_or1knd)
2264559860eSchristos     or1k_cpucfgr |= SPR_FIELD_MASK_SYS_CPUCFGR_ND;
2274559860eSchristos   else
2284559860eSchristos     or1k_cpucfgr &= ~SPR_FIELD_MASK_SYS_CPUCFGR_ND;
2294559860eSchristos 
2304559860eSchristos   /* Open a copy of the cpu descriptor table and initialize the
2314559860eSchristos      disassembler.  These initialization functions are generated by CGEN
2324559860eSchristos      using the binutils scheme cpu description files.  */
2334559860eSchristos   {
2344559860eSchristos     CGEN_CPU_DESC cd =
2354559860eSchristos       or1k_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
2364559860eSchristos 			    CGEN_ENDIAN_BIG);
2374559860eSchristos     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
2384559860eSchristos       {
2394559860eSchristos 	SIM_CPU *cpu = STATE_CPU (sd, i);
2404559860eSchristos 	CPU_CPU_DESC (cpu) = cd;
2414559860eSchristos 	CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
2424559860eSchristos       }
2434559860eSchristos     or1k_cgen_init_dis (cd);
2444559860eSchristos   }
2454559860eSchristos 
2464559860eSchristos   /* Do some final OpenRISC sim specific initializations.  */
247*0388e998Schristos   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
2484559860eSchristos     {
2494559860eSchristos       SIM_CPU *cpu = STATE_CPU (sd, i);
2504559860eSchristos       /* Only needed for profiling, but the structure member is small.  */
2514559860eSchristos       memset (CPU_OR1K_MISC_PROFILE (cpu), 0,
2524559860eSchristos 	      sizeof (*CPU_OR1K_MISC_PROFILE (cpu)));
2534559860eSchristos 
2544559860eSchristos       or1k_cpu_init (sd, cpu, or1k_vr, or1k_upr, or1k_cpucfgr);
2554559860eSchristos     }
2564559860eSchristos 
2574559860eSchristos   return sd;
2584559860eSchristos }
2594559860eSchristos 
2604559860eSchristos 
2614559860eSchristos SIM_RC
2624559860eSchristos sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
2634559860eSchristos 		     char * const *argv, char * const *envp)
2644559860eSchristos {
2654559860eSchristos   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
266*0388e998Schristos   bfd_vma addr;
2674559860eSchristos 
2684559860eSchristos   if (abfd != NULL)
2694559860eSchristos     addr = bfd_get_start_address (abfd);
2704559860eSchristos   else
2714559860eSchristos     addr = 0;
2724559860eSchristos   sim_pc_set (current_cpu, addr);
2734559860eSchristos 
2744559860eSchristos   return SIM_RC_OK;
2754559860eSchristos }
276