Home | History | Annotate | Line # | Download | only in riscv
interp.c revision 1.1.1.1
      1 /* RISC-V simulator.
      2 
      3    Copyright (C) 2005-2023 Free Software Foundation, Inc.
      4    Contributed by Mike Frysinger.
      5 
      6    This file is part of simulators.
      7 
      8    This program is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3 of the License, or
     11    (at your option) any later version.
     12 
     13    This program is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20 
     21 /* This must come before any other includes.  */
     22 #include "defs.h"
     23 
     24 #include "sim/callback.h"
     25 #include "sim-main.h"
     26 #include "sim-options.h"
     27 #include "target-newlib-syscall.h"
     28 
     29 void
     31 sim_engine_run (SIM_DESC sd,
     32 		int next_cpu_nr, /* ignore  */
     33 		int nr_cpus, /* ignore  */
     34 		int siggnal) /* ignore  */
     35 {
     36   SIM_CPU *cpu;
     37 
     38   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
     39 
     40   cpu = STATE_CPU (sd, 0);
     41 
     42   while (1)
     43     {
     44       step_once (cpu);
     45       if (sim_events_tick (sd))
     46 	sim_events_process (sd);
     47     }
     48 }
     49 
     50 static void
     52 free_state (SIM_DESC sd)
     53 {
     54   if (STATE_MODULES (sd) != NULL)
     55     sim_module_uninstall (sd);
     56   sim_cpu_free_all (sd);
     57   sim_state_free (sd);
     58 }
     59 
     60 extern const SIM_MACH * const riscv_sim_machs[];
     61 
     62 SIM_DESC
     63 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
     64 	  struct bfd *abfd, char * const *argv)
     65 {
     66   char c;
     67   int i;
     68   SIM_DESC sd = sim_state_alloc_extra (kind, callback,
     69 				       sizeof (struct riscv_sim_state));
     70 
     71   /* Set default options before parsing user options.  */
     72   STATE_MACHS (sd) = riscv_sim_machs;
     73   STATE_MODEL_NAME (sd) = WITH_TARGET_WORD_BITSIZE == 32 ? "RV32G" : "RV64G";
     74   current_target_byte_order = BFD_ENDIAN_LITTLE;
     75   callback->syscall_map = cb_riscv_syscall_map;
     76 
     77   /* The cpu data is kept in a separately allocated chunk of memory.  */
     78   if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
     79     {
     80       free_state (sd);
     81       return 0;
     82     }
     83 
     84   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
     85     {
     86       free_state (sd);
     87       return 0;
     88     }
     89 
     90   /* XXX: Default to the Virtual environment.  */
     91   if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
     92     STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
     93 
     94   /* The parser will print an error message for us, so we silently return.  */
     95   if (sim_parse_args (sd, argv) != SIM_RC_OK)
     96     {
     97       free_state (sd);
     98       return 0;
     99     }
    100 
    101   /* Check for/establish the a reference program image.  */
    102   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
    103     {
    104       free_state (sd);
    105       return 0;
    106     }
    107 
    108   /* Establish any remaining configuration options.  */
    109   if (sim_config (sd) != SIM_RC_OK)
    110     {
    111       free_state (sd);
    112       return 0;
    113     }
    114 
    115   if (sim_post_argv_init (sd) != SIM_RC_OK)
    116     {
    117       free_state (sd);
    118       return 0;
    119     }
    120 
    121   /* CPU specific initialization.  */
    122   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    123     {
    124       SIM_CPU *cpu = STATE_CPU (sd, i);
    125 
    126       initialize_cpu (sd, cpu, i);
    127     }
    128 
    129   /* Allocate external memory if none specified by user.
    130      Use address 4 here in case the user wanted address 0 unmapped.  */
    131   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
    132     sim_do_commandf (sd, "memory-size %#x", DEFAULT_MEM_SIZE);
    133 
    134   return sd;
    135 }
    136 
    137 SIM_RC
    139 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
    140 		     char * const *argv, char * const *env)
    141 {
    142   SIM_CPU *cpu = STATE_CPU (sd, 0);
    143   host_callback *cb = STATE_CALLBACK (sd);
    144   SIM_ADDR addr;
    145 
    146   /* Set the PC.  */
    147   if (abfd != NULL)
    148     addr = bfd_get_start_address (abfd);
    149   else
    150     addr = 0;
    151   sim_pc_set (cpu, addr);
    152 
    153   /* Standalone mode (i.e. `run`) will take care of the argv for us in
    154      sim_open() -> sim_parse_args().  But in debug mode (i.e. 'target sim'
    155      with `gdb`), we need to handle it because the user can change the
    156      argv on the fly via gdb's 'run'.  */
    157   if (STATE_PROG_ARGV (sd) != argv)
    158     {
    159       freeargv (STATE_PROG_ARGV (sd));
    160       STATE_PROG_ARGV (sd) = dupargv (argv);
    161     }
    162 
    163   if (STATE_PROG_ENVP (sd) != env)
    164     {
    165       freeargv (STATE_PROG_ENVP (sd));
    166       STATE_PROG_ENVP (sd) = dupargv (env);
    167     }
    168 
    169   cb->argv = STATE_PROG_ARGV (sd);
    170   cb->envp = STATE_PROG_ENVP (sd);
    171 
    172   initialize_env (sd, (void *)argv, (void *)env);
    173 
    174   return SIM_RC_OK;
    175 }
    176