1a5a4af3bSchristos /* Main simulator entry points specific to Lattice Mico32. 2a5a4af3bSchristos Contributed by Jon Beniston <jon@beniston.com> 3a5a4af3bSchristos 4*8b657b07Schristos Copyright (C) 2009-2023 Free Software Foundation, Inc. 5a5a4af3bSchristos 6a5a4af3bSchristos This file is part of GDB. 7a5a4af3bSchristos 8a5a4af3bSchristos This program is free software; you can redistribute it and/or modify 9a5a4af3bSchristos it under the terms of the GNU General Public License as published by 10a5a4af3bSchristos the Free Software Foundation; either version 3 of the License, or 11a5a4af3bSchristos (at your option) any later version. 12a5a4af3bSchristos 13a5a4af3bSchristos This program is distributed in the hope that it will be useful, 14a5a4af3bSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 15a5a4af3bSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16a5a4af3bSchristos GNU General Public License for more details. 17a5a4af3bSchristos 18a5a4af3bSchristos You should have received a copy of the GNU General Public License 19a5a4af3bSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20a5a4af3bSchristos 21*8b657b07Schristos /* This must come before any other includes. */ 22*8b657b07Schristos #include "defs.h" 23*8b657b07Schristos 24*8b657b07Schristos #include <stdlib.h> 25*8b657b07Schristos 26*8b657b07Schristos #include "sim/callback.h" 27a5a4af3bSchristos #include "sim-main.h" 28a5a4af3bSchristos #include "sim-options.h" 29a5a4af3bSchristos #include "libiberty.h" 30a5a4af3bSchristos #include "bfd.h" 31a5a4af3bSchristos 32a5a4af3bSchristos /* Cover function of sim_state_free to free the cpu buffers as well. */ 33a5a4af3bSchristos 34a5a4af3bSchristos static void 35a5a4af3bSchristos free_state (SIM_DESC sd) 36a5a4af3bSchristos { 37a5a4af3bSchristos if (STATE_MODULES (sd) != NULL) 38a5a4af3bSchristos sim_module_uninstall (sd); 39a5a4af3bSchristos sim_cpu_free_all (sd); 40a5a4af3bSchristos sim_state_free (sd); 41a5a4af3bSchristos } 42a5a4af3bSchristos 43a5a4af3bSchristos /* Find memory range used by program. */ 44a5a4af3bSchristos 45a5a4af3bSchristos static unsigned long 46a5a4af3bSchristos find_base (bfd *prog_bfd) 47a5a4af3bSchristos { 48a5a4af3bSchristos int found; 49a5a4af3bSchristos unsigned long base = ~(0UL); 50a5a4af3bSchristos asection *s; 51a5a4af3bSchristos 52a5a4af3bSchristos found = 0; 53a5a4af3bSchristos for (s = prog_bfd->sections; s; s = s->next) 54a5a4af3bSchristos { 5582650ea5Schristos if ((strcmp (bfd_section_name (s), ".boot") == 0) 5682650ea5Schristos || (strcmp (bfd_section_name (s), ".text") == 0) 5782650ea5Schristos || (strcmp (bfd_section_name (s), ".data") == 0) 5882650ea5Schristos || (strcmp (bfd_section_name (s), ".bss") == 0)) 59a5a4af3bSchristos { 60a5a4af3bSchristos if (!found) 61a5a4af3bSchristos { 6282650ea5Schristos base = bfd_section_vma (s); 63a5a4af3bSchristos found = 1; 64a5a4af3bSchristos } 65a5a4af3bSchristos else 6682650ea5Schristos base = bfd_section_vma (s) < base ? bfd_section_vma (s) : base; 67a5a4af3bSchristos } 68a5a4af3bSchristos } 69a5a4af3bSchristos return base & ~(0xffffUL); 70a5a4af3bSchristos } 71a5a4af3bSchristos 72a5a4af3bSchristos static unsigned long 7399e23f81Schristos find_limit (SIM_DESC sd) 74a5a4af3bSchristos { 7599e23f81Schristos bfd_vma addr; 76a5a4af3bSchristos 7799e23f81Schristos addr = trace_sym_value (sd, "_fstack"); 7899e23f81Schristos if (addr == -1) 79a5a4af3bSchristos return 0; 80a5a4af3bSchristos 8199e23f81Schristos return (addr + 65536) & ~(0xffffUL); 82a5a4af3bSchristos } 83a5a4af3bSchristos 84*8b657b07Schristos extern const SIM_MACH * const lm32_sim_machs[]; 85*8b657b07Schristos 86a5a4af3bSchristos /* Create an instance of the simulator. */ 87a5a4af3bSchristos 88a5a4af3bSchristos SIM_DESC 89*8b657b07Schristos sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd, 90*8b657b07Schristos char * const *argv) 91a5a4af3bSchristos { 92a5a4af3bSchristos SIM_DESC sd = sim_state_alloc (kind, callback); 93a5a4af3bSchristos char c; 94a5a4af3bSchristos int i; 95a5a4af3bSchristos unsigned long base, limit; 96a5a4af3bSchristos 97*8b657b07Schristos /* Set default options before parsing user options. */ 98*8b657b07Schristos STATE_MACHS (sd) = lm32_sim_machs; 99*8b657b07Schristos STATE_MODEL_NAME (sd) = "lm32"; 100*8b657b07Schristos current_alignment = STRICT_ALIGNMENT; 101*8b657b07Schristos current_target_byte_order = BFD_ENDIAN_BIG; 102*8b657b07Schristos 103a5a4af3bSchristos /* The cpu data is kept in a separately allocated chunk of memory. */ 104*8b657b07Schristos if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK) 105a5a4af3bSchristos { 106a5a4af3bSchristos free_state (sd); 107a5a4af3bSchristos return 0; 108a5a4af3bSchristos } 109a5a4af3bSchristos 110a5a4af3bSchristos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 111a5a4af3bSchristos { 112a5a4af3bSchristos free_state (sd); 113a5a4af3bSchristos return 0; 114a5a4af3bSchristos } 115a5a4af3bSchristos 116e5cb852cSchristos /* The parser will print an error message for us, so we silently return. */ 117a5a4af3bSchristos if (sim_parse_args (sd, argv) != SIM_RC_OK) 118a5a4af3bSchristos { 119a5a4af3bSchristos free_state (sd); 120a5a4af3bSchristos return 0; 121a5a4af3bSchristos } 122a5a4af3bSchristos 123a5a4af3bSchristos #if 0 124a5a4af3bSchristos /* Allocate a handler for I/O devices 125a5a4af3bSchristos if no memory for that range has been allocated by the user. 126a5a4af3bSchristos All are allocated in one chunk to keep things from being 127a5a4af3bSchristos unnecessarily complicated. */ 128a5a4af3bSchristos if (sim_core_read_buffer (sd, NULL, read_map, &c, LM32_DEVICE_ADDR, 1) == 0) 129a5a4af3bSchristos sim_core_attach (sd, NULL, 0 /*level */ , 130a5a4af3bSchristos access_read_write, 0 /*space ??? */ , 131a5a4af3bSchristos LM32_DEVICE_ADDR, LM32_DEVICE_LEN /*nr_bytes */ , 132a5a4af3bSchristos 0 /*modulo */ , 133a5a4af3bSchristos &lm32_devices, NULL /*buffer */ ); 134a5a4af3bSchristos #endif 135a5a4af3bSchristos 136a5a4af3bSchristos /* check for/establish the reference program image. */ 137*8b657b07Schristos if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 138a5a4af3bSchristos { 139a5a4af3bSchristos free_state (sd); 140a5a4af3bSchristos return 0; 141a5a4af3bSchristos } 142a5a4af3bSchristos 143a5a4af3bSchristos /* Check to see if memory exists at programs start address. */ 144a5a4af3bSchristos if (sim_core_read_buffer (sd, NULL, read_map, &c, STATE_START_ADDR (sd), 1) 145a5a4af3bSchristos == 0) 146a5a4af3bSchristos { 147a5a4af3bSchristos if (STATE_PROG_BFD (sd) != NULL) 148a5a4af3bSchristos { 149a5a4af3bSchristos /* It doesn't, so we should try to allocate enough memory to hold program. */ 150a5a4af3bSchristos base = find_base (STATE_PROG_BFD (sd)); 15199e23f81Schristos limit = find_limit (sd); 152a5a4af3bSchristos if (limit == 0) 153a5a4af3bSchristos { 154a5a4af3bSchristos sim_io_eprintf (sd, 155a5a4af3bSchristos "Failed to find symbol _fstack in program. You must specify memory regions with --memory-region.\n"); 156a5a4af3bSchristos free_state (sd); 157a5a4af3bSchristos return 0; 158a5a4af3bSchristos } 159*8b657b07Schristos /*sim_io_printf (sd, "Allocating memory at 0x%lx size 0x%lx\n", base, limit); */ 160*8b657b07Schristos sim_do_commandf (sd, "memory region 0x%lx,0x%lx", base, limit); 161a5a4af3bSchristos } 162a5a4af3bSchristos } 163a5a4af3bSchristos 164a5a4af3bSchristos /* Establish any remaining configuration options. */ 165a5a4af3bSchristos if (sim_config (sd) != SIM_RC_OK) 166a5a4af3bSchristos { 167a5a4af3bSchristos free_state (sd); 168a5a4af3bSchristos return 0; 169a5a4af3bSchristos } 170a5a4af3bSchristos 171a5a4af3bSchristos if (sim_post_argv_init (sd) != SIM_RC_OK) 172a5a4af3bSchristos { 173a5a4af3bSchristos free_state (sd); 174a5a4af3bSchristos return 0; 175a5a4af3bSchristos } 176a5a4af3bSchristos 177a5a4af3bSchristos /* Open a copy of the cpu descriptor table. */ 178a5a4af3bSchristos { 179a5a4af3bSchristos CGEN_CPU_DESC cd = 180a5a4af3bSchristos lm32_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name, 181a5a4af3bSchristos CGEN_ENDIAN_BIG); 182a5a4af3bSchristos for (i = 0; i < MAX_NR_PROCESSORS; ++i) 183a5a4af3bSchristos { 184a5a4af3bSchristos SIM_CPU *cpu = STATE_CPU (sd, i); 185a5a4af3bSchristos CPU_CPU_DESC (cpu) = cd; 186a5a4af3bSchristos CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn; 187a5a4af3bSchristos } 188a5a4af3bSchristos lm32_cgen_init_dis (cd); 189a5a4af3bSchristos } 190a5a4af3bSchristos 191a5a4af3bSchristos return sd; 192a5a4af3bSchristos } 193a5a4af3bSchristos 194a5a4af3bSchristos SIM_RC 195*8b657b07Schristos sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char * const *argv, 196*8b657b07Schristos char * const *env) 197a5a4af3bSchristos { 198a5a4af3bSchristos SIM_CPU *current_cpu = STATE_CPU (sd, 0); 199*8b657b07Schristos host_callback *cb = STATE_CALLBACK (sd); 200a5a4af3bSchristos SIM_ADDR addr; 201a5a4af3bSchristos 202a5a4af3bSchristos if (abfd != NULL) 203a5a4af3bSchristos addr = bfd_get_start_address (abfd); 204a5a4af3bSchristos else 205a5a4af3bSchristos addr = 0; 206a5a4af3bSchristos sim_pc_set (current_cpu, addr); 207a5a4af3bSchristos 208e5cb852cSchristos /* Standalone mode (i.e. `run`) will take care of the argv for us in 209e5cb852cSchristos sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim' 210e5cb852cSchristos with `gdb`), we need to handle it because the user can change the 211e5cb852cSchristos argv on the fly via gdb's 'run'. */ 212e5cb852cSchristos if (STATE_PROG_ARGV (sd) != argv) 213e5cb852cSchristos { 214e5cb852cSchristos freeargv (STATE_PROG_ARGV (sd)); 215e5cb852cSchristos STATE_PROG_ARGV (sd) = dupargv (argv); 216e5cb852cSchristos } 217a5a4af3bSchristos 218*8b657b07Schristos if (STATE_PROG_ENVP (sd) != env) 219*8b657b07Schristos { 220*8b657b07Schristos freeargv (STATE_PROG_ENVP (sd)); 221*8b657b07Schristos STATE_PROG_ENVP (sd) = dupargv (env); 222*8b657b07Schristos } 223*8b657b07Schristos 224*8b657b07Schristos cb->argv = STATE_PROG_ARGV (sd); 225*8b657b07Schristos cb->envp = STATE_PROG_ENVP (sd); 226*8b657b07Schristos 227a5a4af3bSchristos return SIM_RC_OK; 228a5a4af3bSchristos } 229