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