X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fm32r%2Fsim-if.c;h=307c607d8ea8e981aca4a0d0898fa905487d5995;hb=160f8a8f32f5566077e4a4b13943bc7c70bc5da2;hp=7f4e10247d5efceb2b4c3b1c0e854727e182e2e5;hpb=7230ff0faa65304b835fc525e52ddb6e3ba70325;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/m32r/sim-if.c b/sim/m32r/sim-if.c index 7f4e10247d..307c607d8e 100644 --- a/sim/m32r/sim-if.c +++ b/sim/m32r/sim-if.c @@ -1,37 +1,53 @@ -/* Main simulator entry points for the M32R. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Main simulator entry points specific to the M32R. + Copyright (C) 1996-2020 Free Software Foundation, Inc. Contributed by Cygnus Support. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. + This file is part of GDB, the GNU debugger. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "sim-main.h" -#include +#include "sim-options.h" +#include "libiberty.h" +#include "bfd.h" + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif #ifdef HAVE_STDLIB_H #include #endif -#include "libiberty.h" -#include "bfd.h" -#include "sim-core.h" -#include "cpu-sim.h" -/* Global state until sim_open starts creating and returning it - [and the other simulator i/f fns take it as an argument]. */ -struct sim_state sim_global_state; +#include "dv-m32r_uart.h" -/* FIXME: Do we *need* to pass state to the semantic routines? */ -STATE current_state; +static void free_state (SIM_DESC); +static void print_m32r_misc_cpu (SIM_CPU *cpu, int verbose); + +/* Cover function of sim_state_free to free the cpu buffers as well. */ + +static void +free_state (SIM_DESC sd) +{ + if (STATE_MODULES (sd) != NULL) + sim_module_uninstall (sd); + sim_cpu_free_all (sd); + sim_state_free (sd); +} /* Create an instance of the simulator. */ @@ -39,140 +55,143 @@ SIM_DESC sim_open (kind, callback, abfd, argv) SIM_OPEN_KIND kind; host_callback *callback; - struct _bfd *abfd; - char **argv; + struct bfd *abfd; + char * const *argv; { + SIM_DESC sd = sim_state_alloc (kind, callback); + char c; int i; - SIM_DESC sd = &sim_global_state; - - /* FIXME: until we alloc one, use the global. */ - memset (sd, 0, sizeof (sim_global_state)); - STATE_OPEN_KIND (sd) = kind; - STATE_CALLBACK (sd) = callback; - if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) - return 0; + /* The cpu data is kept in a separately allocated chunk of memory. */ + if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK) + { + free_state (sd); + return 0; + } -#if 0 /* FIXME: 'twould be nice if we could do this */ - /* These options override any module options. - Obviously ambiguity should be avoided, however the caller may wish to - augment the meaning of an option. */ - if (extra_options != NULL) - sim_add_option_table (sd, extra_options); +#if 0 /* FIXME: pc is in mach-specific struct */ + /* FIXME: watchpoints code shouldn't need this */ + { + SIM_CPU *current_cpu = STATE_CPU (sd, 0); + STATE_WATCHPOINTS (sd)->pc = &(PC); + STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); + } #endif - /* getopt will print the error message so we just have to exit if this fails. - FIXME: Hmmm... in the case of gdb we need getopt to call - print_filtered. */ - if (sim_parse_args (sd, argv) != SIM_RC_OK) + if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) { - sim_module_uninstall (sd); + free_state (sd); return 0; } - if (sim_post_argv_init (sd) != SIM_RC_OK) + /* The parser will print an error message for us, so we silently return. */ + if (sim_parse_args (sd, argv) != SIM_RC_OK) { - sim_module_uninstall (sd); + free_state (sd); return 0; } - /* Initialize various cgen things not done by common framework. */ - cgen_init (sd); - - /* FIXME:wip */ - sim_core_attach (sd, NULL, attach_raw_memory, access_read_write_exec, - 0, 0, M32R_DEFAULT_MEM_SIZE, NULL, NULL); + /* Allocate a handler for the control registers and other devices + if no memory for that range has been allocated by the user. + All are allocated in one chunk to keep things from being + unnecessarily complicated. + TODO: Move these to the sim-model framework. */ + sim_hw_parse (sd, "/core/%s/reg %#x %i", "m32r_uart", UART_BASE_ADDR, 0x100); + sim_hw_parse (sd, "/core/%s/reg %#x %i", "m32r_cache", 0xfffffff0, 0x10); + + /* Allocate core managed memory if none specified by user. + Use address 4 here in case the user wanted address 0 unmapped. */ + if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0) + sim_do_commandf (sd, "memory region 0,0x%x", M32R_DEFAULT_MEM_SIZE); + + /* check for/establish the reference program image */ + if (sim_analyze_program (sd, + (STATE_PROG_ARGV (sd) != NULL + ? *STATE_PROG_ARGV (sd) + : NULL), + abfd) != SIM_RC_OK) + { + free_state (sd); + return 0; + } - /* Only needed for profiling, but the structure member is small. */ - for (i = 0; i < MAX_NR_PROCESSORS; ++i) - memset (& CPU_M32R_PROFILE (STATE_CPU (sd, i)), 0, - sizeof (CPU_M32R_PROFILE (STATE_CPU (sd, i)))); + /* Establish any remaining configuration options. */ + if (sim_config (sd) != SIM_RC_OK) + { + free_state (sd); + return 0; + } - return &sim_global_state; -} + if (sim_post_argv_init (sd) != SIM_RC_OK) + { + free_state (sd); + return 0; + } -void -sim_close (sd, quitting) - SIM_DESC sd; - int quitting; -{ - sim_module_uninstall (sd); -} + /* Open a copy of the cpu descriptor table. */ + { + CGEN_CPU_DESC cd = m32r_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name, + CGEN_ENDIAN_BIG); + for (i = 0; i < MAX_NR_PROCESSORS; ++i) + { + SIM_CPU *cpu = STATE_CPU (sd, i); + CPU_CPU_DESC (cpu) = cd; + CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn; + } + m32r_cgen_init_dis (cd); + } -SIM_RC -sim_load (sd, prog, abfd, from_tty) - SIM_DESC sd; - char *prog; - bfd *abfd; - int from_tty; -{ - extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ - bfd *prog_bfd; + /* Initialize various cgen things not done by common framework. + Must be done after m32r_cgen_cpu_open. */ + cgen_init (sd); - prog_bfd = sim_load_file (sd, STATE_MY_NAME (sd), - STATE_CALLBACK (sd), - prog, - /* pass NULL for abfd, we always open our own */ - NULL, - STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG); - if (prog_bfd == NULL) - return SIM_RC_FAIL; - sim_analyze_program (sd, prog_bfd); - STATE_CPU_CPU (sd, 0)->pc = STATE_START_ADDR (sd); - return SIM_RC_OK; -} + for (c = 0; c < MAX_NR_PROCESSORS; ++c) + { + /* Only needed for profiling, but the structure member is small. */ + memset (CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)), 0, + sizeof (* CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)))); + /* Hook in callback for reporting these stats */ + PROFILE_INFO_CPU_CALLBACK (CPU_PROFILE_DATA (STATE_CPU (sd, i))) + = print_m32r_misc_cpu; + } + return sd; +} + SIM_RC -sim_create_inferior (sd, argv, envp) +sim_create_inferior (sd, abfd, argv, envp) SIM_DESC sd; - char **argv; - char **envp; + struct bfd *abfd; + char * const *argv; + char * const *envp; { -#if 0 - STATE_ARGV (sd) = sim_copy_argv (argv); - STATE_ENVP (sd) = sim_copy_argv (envp); + SIM_CPU *current_cpu = STATE_CPU (sd, 0); + SIM_ADDR addr; + + if (abfd != NULL) + addr = bfd_get_start_address (abfd); + else + addr = 0; + sim_pc_set (current_cpu, addr); + +#ifdef M32R_LINUX + m32rbf_h_cr_set (current_cpu, + m32r_decode_gdb_ctrl_regnum(SPI_REGNUM), 0x1f00000); + m32rbf_h_cr_set (current_cpu, + m32r_decode_gdb_ctrl_regnum(SPU_REGNUM), 0x1f00000); #endif - return SIM_RC_OK; -} - -int -sim_stop (SIM_DESC sd) -{ - return engine_stop (sd); -} -void -sim_resume (sd, step, siggnal) - SIM_DESC sd; - int step, siggnal; -{ - engine_run (sd, step, siggnal); -} - -void -sim_stop_reason (sd, reason, sigrc) - SIM_DESC sd; - enum sim_stop *reason; - int *sigrc; -{ - sim_cpu *cpu = STATE_CPU (sd, 0); - - /* Map sim_state to sim_stop. */ - switch (CPU_EXEC_STATE (cpu)) + /* Standalone mode (i.e. `run`) will take care of the argv for us in + sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim' + with `gdb`), we need to handle it because the user can change the + argv on the fly via gdb's 'run'. */ + if (STATE_PROG_ARGV (sd) != argv) { - case EXEC_STATE_EXITED : - *reason = sim_exited; - *sigrc = CPU_HALT_SIGRC (cpu); - break; - case EXEC_STATE_STOPPED : - *reason = sim_stopped; - *sigrc = sim_signal_to_host (CPU_HALT_SIGRC (cpu)); - break; - case EXEC_STATE_SIGNALLED : - *reason = sim_signalled; - *sigrc = sim_signal_to_host (CPU_HALT_SIGRC (cpu)); - break; + freeargv (STATE_PROG_ARGV (sd)); + STATE_PROG_ARGV (sd) = dupargv (argv); } + + return SIM_RC_OK; } /* PROFILE_CPU_CALLBACK */ @@ -189,121 +208,16 @@ print_m32r_misc_cpu (SIM_CPU *cpu, int verbose) sim_io_printf (sd, " %-*s %s\n\n", PROFILE_LABEL_WIDTH, "Fill nops:", sim_add_commas (buf, sizeof (buf), - CPU_M32R_PROFILE (cpu).fillnop_count)); + CPU_M32R_MISC_PROFILE (cpu)->fillnop_count)); + if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32rx) + sim_io_printf (sd, " %-*s %s\n\n", + PROFILE_LABEL_WIDTH, "Parallel insns:", + sim_add_commas (buf, sizeof (buf), + CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); + if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32r2) + sim_io_printf (sd, " %-*s %s\n\n", + PROFILE_LABEL_WIDTH, "Parallel insns:", + sim_add_commas (buf, sizeof (buf), + CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); } } - -void -sim_info (sd, verbose) - SIM_DESC sd; - int verbose; -{ - profile_print (sd, STATE_VERBOSE_P (sd), NULL, print_m32r_misc_cpu); -} - -/* The contents of BUF are in target byte order. */ - -void -sim_fetch_register (sd, rn, buf) - SIM_DESC sd; - int rn; - unsigned char *buf; -{ - if (rn < 16) - SETTWI (buf, STATE_CPU_CPU (sd, 0)->h_gr[rn]); - else if (rn < 21) - SETTWI (buf, STATE_CPU_CPU (sd, 0)->h_cr[rn - 16]); - else switch (rn) { - case PC_REGNUM: - SETTWI (buf, STATE_CPU_CPU (sd, 0)->pc); - break; - case ACCL_REGNUM: - SETTWI (buf, GETLODI (STATE_CPU_CPU (sd, 0)->h_accum)); - break; - case ACCH_REGNUM: - SETTWI (buf, GETHIDI (STATE_CPU_CPU (sd, 0)->h_accum)); - break; -#if 0 - case 23: *reg = STATE_CPU_CPU (sd, 0)->h_cond; break; - case 24: *reg = STATE_CPU_CPU (sd, 0)->h_sm; break; - case 25: *reg = STATE_CPU_CPU (sd, 0)->h_bsm; break; - case 26: *reg = STATE_CPU_CPU (sd, 0)->h_ie; break; - case 27: *reg = STATE_CPU_CPU (sd, 0)->h_bie; break; - case 28: *reg = STATE_CPU_CPU (sd, 0)->h_bcarry; break; /* rename: bc */ - case 29: memcpy (buf, &STATE_CPU_CPU (sd, 0)->h_bpc, sizeof(WI)); break; /* duplicate */ -#endif - default: abort (); - } -} - -/* The contents of BUF are in target byte order. */ - -void -sim_store_register (sd, rn, buf) - SIM_DESC sd; - int rn; - unsigned char *buf; -{ - if (rn < 16) - STATE_CPU_CPU (sd, 0)->h_gr[rn] = GETTWI (buf); - else if (rn < 21) - STATE_CPU_CPU (sd, 0)->h_cr[rn - 16] = GETTWI (buf); - else switch (rn) { - case PC_REGNUM: - STATE_CPU_CPU (sd, 0)->pc = GETTWI (buf); - break; - case ACCL_REGNUM: - SETLODI (STATE_CPU_CPU (sd, 0)->h_accum, GETTWI (buf)); - break; - case ACCH_REGNUM: - SETHIDI (STATE_CPU_CPU (sd, 0)->h_accum, GETTWI (buf)); - break; -#if 0 - case 23: STATE_CPU_CPU (sd, 0)->h_cond = *reg; break; - case 24: STATE_CPU_CPU (sd, 0)->h_sm = *reg; break; - case 25: STATE_CPU_CPU (sd, 0)->h_bsm = *reg; break; - case 26: STATE_CPU_CPU (sd, 0)->h_ie = *reg; break; - case 27: STATE_CPU_CPU (sd, 0)->h_bie = *reg; break; - case 28: STATE_CPU_CPU (sd, 0)->h_bcarry = *reg; break; /* rename: bc */ - case 29: memcpy (&STATE_CPU_CPU (sd, 0)->h_bpc, buf, sizeof(DI)); break; /* duplicate */ -#endif - } -} - -int -sim_read (sd, addr, buf, len) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buf; - int len; -{ -#if 1 - return sim_core_read_buffer (sd, NULL, sim_core_read_map, - buf, addr, len); -#else - return (*STATE_MEM_READ (sd)) (sd, addr, buf, len); -#endif -} - -int -sim_write (sd, addr, buf, len) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buf; - int len; -{ -#if 1 - return sim_core_write_buffer (sd, NULL, sim_core_write_map, - buf, addr, len); -#else - return (*STATE_MEM_WRITE (sd)) (sd, addr, buf, len); -#endif -} - -void -sim_do_command (sd, cmd) - SIM_DESC sd; - char *cmd; -{ - sim_io_error (sd, "sim_do_command - unimplemented"); -}