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