]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/m32r/sim-if.c
sim: m32r: migrate from WITH_DEVICES to WITH_HW
[thirdparty/binutils-gdb.git] / sim / m32r / sim-if.c
index 36c1644515f7f19de6d9541711d13b8fef7ddb4e..639976d5e0f724df339228fa1e7c7ae7e6b4d6b0 100644 (file)
@@ -1,29 +1,39 @@
-/* Main simulator entry points for the M32R.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Main simulator entry points specific to the M32R.
+   Copyright (C) 1996-2015 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 <http://www.gnu.org/licenses/>.  */
 
 #include "sim-main.h"
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
 #include "sim-options.h"
 #include "libiberty.h"
 #include "bfd.h"
-#include "targ-vals.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "dv-m32r_uart.h"
 
 static void free_state (SIM_DESC);
 static void print_m32r_misc_cpu (SIM_CPU *cpu, int verbose);
@@ -49,10 +59,12 @@ SIM_DESC
 sim_open (kind, callback, abfd, argv)
      SIM_OPEN_KIND kind;
      host_callback *callback;
-     struct _bfd *abfd;
+     struct bfd *abfd;
      char **argv;
 {
   SIM_DESC sd = sim_state_alloc (kind, callback);
+  char c;
+  int i;
 
   /* 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)
@@ -84,19 +96,6 @@ sim_open (kind, callback, abfd, argv)
     sim_add_option_table (sd, extra_options);
 #endif
 
-  /* Allocate core managed memory */
-  sim_do_commandf (sd, "memory region 0,0x%lx", M32R_DEFAULT_MEM_SIZE);
-
-  /* Allocate a handler for the MSPR register.  */
-  sim_core_attach (sd, NULL,
-                  0 /*level*/,
-                  access_read_write,
-                  0 /*space ???*/,
-                  M32R_DEVICE_ADDR, M32R_DEVICE_LEN /*nr_bytes*/,
-                  0 /*modulo*/,
-                  &m32r_devices,
-                  NULL /*buffer*/);
-
   /* 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.  */
@@ -106,6 +105,19 @@ sim_open (kind, callback, abfd, argv)
       return 0;
     }
 
+  /* 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
@@ -117,47 +129,6 @@ sim_open (kind, callback, abfd, argv)
       return 0;
     }
 
-  /* If both cpu model and state architecture are set, ensure they're
-     compatible.  If only one is set, set the other.  If neither are set,
-     use the default model.  STATE_ARCHITECTURE is the bfd_arch_info data
-     for the selected "mach" (bfd terminology).  */
-  {
-    SIM_CPU *cpu = STATE_CPU (sd, 0);
-
-    if (! STATE_ARCHITECTURE (sd)
-       /* Only check cpu 0.  STATE_ARCHITECTURE is for that one only.  */
-       && ! CPU_MACH (cpu))
-      {
-       /* Set the default model.  */
-       const MODEL *model = sim_model_lookup (WITH_DEFAULT_MODEL);
-       sim_model_set (sd, NULL, model);
-      }
-    if (STATE_ARCHITECTURE (sd)
-       && CPU_MACH (cpu))
-      {
-       if (strcmp (STATE_ARCHITECTURE (sd)->printable_name,
-                   MACH_NAME (CPU_MACH (cpu))) != 0)
-         {
-           sim_io_eprintf (sd, "invalid model `%s' for `%s'\n",
-                           MODEL_NAME (CPU_MODEL (cpu)),
-                           STATE_ARCHITECTURE (sd)->printable_name);
-           free_state (sd);
-           return 0;
-         }
-      }
-    else if (STATE_ARCHITECTURE (sd))
-      {
-       /* Use the default model for the selected machine.
-          The default model is the first one in the list.  */
-       const MACH *mach = sim_mach_lookup (STATE_ARCHITECTURE (sd)->printable_name);
-       sim_model_set (sd, NULL, MACH_MODELS (mach));
-      }
-    else
-      {
-        STATE_ARCHITECTURE (sd) = bfd_scan_arch (MACH_NAME (CPU_MACH (cpu)));
-      }
-  }
-
   /* Establish any remaining configuration options.  */
   if (sim_config (sd) != SIM_RC_OK)
     {
@@ -171,42 +142,44 @@ sim_open (kind, callback, abfd, argv)
       return 0;
     }
 
-  /* Initialize various cgen things not done by common framework.  */
-  cgen_init (sd);
-
+  /* Open a copy of the cpu descriptor table.  */
   {
-    int c;
-
-    for (c = 0; c < MAX_NR_PROCESSORS; ++c)
+    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)
       {
-       /* Only needed for profiling, but the structure member is small.  */
-       memset (& CPU_M32R_MISC_PROFILE (STATE_CPU (sd, c)), 0,
-               sizeof (CPU_M32R_MISC_PROFILE (STATE_CPU (sd, c))));
-       /* Hook in callback for reporting these stats */
-       PROFILE_INFO_CPU_CALLBACK (CPU_PROFILE_DATA (STATE_CPU (sd, c)))
-         = print_m32r_misc_cpu;
+       SIM_CPU *cpu = STATE_CPU (sd, i);
+       CPU_CPU_DESC (cpu) = cd;
+       CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
       }
+    m32r_cgen_init_dis (cd);
   }
 
+  /* Initialize various cgen things not done by common framework.
+     Must be done after m32r_cgen_cpu_open.  */
+  cgen_init (sd);
+
+  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;
+    }
+
   /* Store in a global so things like sparc32_dump_regs can be invoked
      from the gdb command line.  */
   current_state = sd;
 
   return sd;
 }
-
-void
-sim_close (sd, quitting)
-     SIM_DESC sd;
-     int quitting;
-{
-  sim_module_uninstall (sd);
-}
 \f
 SIM_RC
 sim_create_inferior (sd, abfd, argv, envp)
      SIM_DESC sd;
-     struct _bfd *abfd;
+     struct bfd *abfd;
      char **argv;
      char **envp;
 {
@@ -219,6 +192,13 @@ sim_create_inferior (sd, abfd, argv, envp)
     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
+
 #if 0
   STATE_ARGV (sd) = sim_copy_argv (argv);
   STATE_ENVP (sd) = sim_copy_argv (envp);
@@ -227,73 +207,6 @@ sim_create_inferior (sd, abfd, argv, envp)
   return SIM_RC_OK;
 }
 
-int
-sim_stop (SIM_DESC sd)
-{
-  switch (STATE_ARCHITECTURE (sd)->mach)
-    {
-    case bfd_mach_m32r :
-      return m32r_engine_stop (sd, NULL, NULL_CIA, sim_stopped, SIM_SIGINT);
-/* start-sanitize-m32rx */
-#ifdef HAVE_CPU_M32RX
-    case bfd_mach_m32rx :
-      return m32rx_engine_stop (sd, NULL, NULL_CIA, sim_stopped, SIM_SIGINT);
-#endif
-/* end-sanitize-m32rx */
-    default :
-      abort ();
-    }
-}
-
-/* This isn't part of the official interface.
-   This is just a good place to put this for now.  */
-
-void
-sim_sync_stop (SIM_DESC sd, SIM_CPU *cpu, PCADDR pc, enum sim_stop reason, int sigrc)
-{
-  switch (STATE_ARCHITECTURE (sd)->mach)
-    {
-    case bfd_mach_m32r :
-      (void) m32r_engine_stop (sd, cpu, pc, reason, sigrc);
-      break;
-/* start-sanitize-m32rx */
-#ifdef HAVE_CPU_M32RX
-    case bfd_mach_m32rx :
-      (void) m32rx_engine_stop (sd, cpu, pc, reason, sigrc);
-      break;
-#endif
-/* end-sanitize-m32rx */
-    default :
-      abort ();
-    }
-}
-
-void
-sim_resume (sd, step, siggnal)
-     SIM_DESC sd;
-     int step, siggnal;
-{
-  sim_module_resume (sd);
-
-  switch (STATE_ARCHITECTURE (sd)->mach)
-    {
-    case bfd_mach_m32r :
-      m32r_engine_run (sd, step, siggnal);
-      break;
-/* start-sanitize-m32rx */
-#ifdef HAVE_CPU_M32RX
-    case bfd_mach_m32rx :
-      m32rx_engine_run (sd, step, siggnal);
-      break;
-#endif
-/* end-sanitize-m32rx */
-    default :
-      abort ();
-    }
-
-  sim_module_suspend (sd);
-}
-
 /* PROFILE_CPU_CALLBACK */
 
 static void
@@ -308,191 +221,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_MISC_PROFILE (cpu).fillnop_count));
-    }
-}
-
-/* The contents of BUF are in target byte order.  */
-
-int
-sim_fetch_register (sd, rn, buf, length)
-     SIM_DESC sd;
-     int rn;
-     unsigned char *buf;
-     int length;
-{
-  SIM_CPU *cpu = STATE_CPU (sd, 0);
-
-  return (* CPU_REG_FETCH (cpu)) (cpu, rn, buf, length);
-}
-/* The contents of BUF are in target byte order.  */
-
-int
-sim_store_register (sd, rn, buf, length)
-     SIM_DESC sd;
-     int rn;
-     unsigned char *buf;
-     int length;
-{
-  SIM_CPU *cpu = STATE_CPU (sd, 0);
-
-  return (* CPU_REG_STORE (cpu)) (cpu, rn, buf, length);
-}
-
-void
-sim_do_command (sd, cmd)
-     SIM_DESC sd;
-     char *cmd;
-{ 
-  if (sim_args_command (sd, cmd) != SIM_RC_OK)
-    sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
-}
-\f
-/* The semantic code invokes this for illegal (unrecognized) instructions.  */
-
-void
-sim_engine_illegal_insn (current_cpu, pc)
-     SIM_CPU *current_cpu;
-     PCADDR pc;
-{
-  sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
-                  sim_stopped, SIM_SIGILL);
-}
-\f
-/* Utility fns to access registers, without knowing the current mach.  */
-
-SI
-h_gr_get (SIM_CPU *current_cpu, UINT regno)
-{
-  switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach)
-    {
-    case bfd_mach_m32r :
-      return m32r_h_gr_get (current_cpu, regno);
-/* start-sanitize-m32rx */
-#ifdef HAVE_CPU_M32RX
-    case bfd_mach_m32rx :
-      return m32rx_h_gr_get (current_cpu, regno);
-#endif
-/* end-sanitize-m32rx */
-    default :
-      abort ();
-    }
-}
-
-void
-h_gr_set (SIM_CPU *current_cpu, UINT regno, SI newval)
-{
-  switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach)
-    {
-    case bfd_mach_m32r :
-      m32r_h_gr_set (current_cpu, regno, newval);
-      break;
-/* start-sanitize-m32rx */
-#ifdef HAVE_CPU_M32RX
-    case bfd_mach_m32rx :
-      m32rx_h_gr_set (current_cpu, regno, newval);
-      break;
-#endif
-/* end-sanitize-m32rx */
-    default :
-      abort ();
+                                    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));
     }
 }
-\f
-/* Read/write functions for system call interface.  */
-
-static int
-syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
-                 unsigned long taddr, char *buf, int bytes)
-{
-  SIM_DESC sd = (SIM_DESC) sc->p1;
-  SIM_CPU *cpu = (SIM_CPU *) sc->p2;
-
-  return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
-}
-
-static int
-syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
-                  unsigned long taddr, const char *buf, int bytes)
-{
-  SIM_DESC sd = (SIM_DESC) sc->p1;
-  SIM_CPU *cpu = (SIM_CPU *) sc->p2;
-
-  return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
-}
-
-/* Trap support.
-   The result is the pc address to continue at.  */
-
-USI
-do_trap (SIM_CPU *current_cpu, int num)
-{
-  SIM_DESC sd = CPU_STATE (current_cpu);
-  host_callback *cb = STATE_CALLBACK (sd);
-
-#ifdef SIM_HAVE_BREAKPOINTS
-  /* Check for breakpoints "owned" by the simulator first, regardless
-     of --environment.  */
-  if (num == 1)
-    {
-      /* First try sim-break.c.  If it's a breakpoint the simulator "owns"
-        it doesn't return.  Otherwise it returns and let's us try.  */
-      sim_handle_breakpoint (sd, current_cpu, sim_pc_get (current_cpu));
-      /* Fall through.  */
-    }
-#endif
-
-  if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
-    {
-      /* The new pc is the trap vector entry.
-        We assume there's a branch there to some handler.  */
-      USI new_pc = num * 4;
-      return new_pc;
-    }
-
-  switch (num)
-    {
-    case 0 :
-      /* Trap 0 is used for system calls.  */
-      {
-       CB_SYSCALL s;
-
-       CB_SYSCALL_INIT (&s);
-       s.func = h_gr_get (current_cpu, 0);
-       s.arg1 = h_gr_get (current_cpu, 1);
-       s.arg2 = h_gr_get (current_cpu, 2);
-       s.arg3 = h_gr_get (current_cpu, 3);
-
-       if (s.func == TARGET_SYS_exit)
-         {
-           sim_engine_halt (sd, current_cpu, NULL, sim_pc_get (current_cpu),
-                            sim_exited, s.arg1);
-         }
-
-       s.p1 = (PTR) sd;
-       s.p2 = (PTR) current_cpu;
-       s.read_mem = syscall_read_mem;
-       s.write_mem = syscall_write_mem;
-       cb_syscall (STATE_CALLBACK (sd), &s);
-       h_gr_set (current_cpu, 2, s.errcode);
-       h_gr_set (current_cpu, 0, s.result);
-       h_gr_set (current_cpu, 1, s.result2);
-       break;
-      }
-
-    case 1:    /* breakpoint trap */
-      sim_engine_halt (sd, current_cpu, NULL, NULL_CIA,
-                      sim_stopped, SIM_SIGTRAP);
-      break;
-
-    default :
-      {
-       USI new_pc = num * 4;
-       return new_pc;
-      }
-    }
-
-  /* Fake an "rte" insn.  */
-  return (sim_pc_get (current_cpu) & -4) + 4;
-}