* traps.c: New file. Trap support moved here from sim-if.c.
authorDoug Evans <dje@google.com>
Thu, 11 Jun 1998 01:05:21 +0000 (01:05 +0000)
committerDoug Evans <dje@google.com>
Thu, 11 Jun 1998 01:05:21 +0000 (01:05 +0000)
* Makefile.in (SIM_OBJS): Add traps.o
* sim-if.c: Don't include targ-vals.h.
(sim_engine_illegal_insn): Moved to traps.c
* sim-main.h (SIM_CORE_SIGNAL): Define.
(m32r_core_signal): Declare.

* devices.c (device_io_read_buffer): Handle cache purging via MCCR
register.

* m32r-sim.h (M32R_MISC_PROFILE): Move here from sim-main.h.
(PROFILE_COUNT_SHORTINSNS,PROFILE_COUNT_LONGINSNS): New macros.
(TRAP_SYSCALL,TRAP_BREAKPOINT): New macros.

sim/m32r/.Sanitize
sim/m32r/ChangeLog
sim/m32r/m32r-sim.h [new file with mode: 0644]
sim/m32r/sim-main.h
sim/m32r/traps.c [new file with mode: 0644]

index f0e0ffa..a92df7a 100644 (file)
@@ -57,6 +57,7 @@ sem.c
 sim-if.c
 sim-main.h
 tconfig.in
+traps.c
 
 Things-to-lose:
 
index 5465fd5..1f6167a 100644 (file)
@@ -1,3 +1,24 @@
+Wed Jun 10 17:39:29 1998  Doug Evans  <devans@canuck.cygnus.com>
+
+       * traps.c: New file.  Trap support moved here from sim-if.c.
+       * Makefile.in (SIM_OBJS): Add traps.o
+       * sim-if.c: Don't include targ-vals.h.
+       (sim_engine_illegal_insn): Moved to traps.c
+       * sim-main.h (SIM_CORE_SIGNAL): Define.
+       (m32r_core_signal): Declare.
+
+       * devices.c (device_io_read_buffer): Handle cache purging via MCCR
+       register.
+
+       * m32r-sim.h (M32R_MISC_PROFILE): Move here from sim-main.h.
+       (PROFILE_COUNT_SHORTINSNS,PROFILE_COUNT_LONGINSNS): New macros.
+       (TRAP_SYSCALL,TRAP_BREAKPOINT): New macros.
+
+       * extract.c,sem-switch.c,sem.c: Regenerate.
+start-sanitize-m32rx
+       * cpux.h,readx.c,semx.c: Regenerate.
+end-sanitize-m32rx
+
 Wed May 20 00:10:40 1998  Doug Evans  <devans@seba.cygnus.com>
 
        * m32r-sim.h (PROFILE_COUNT_PARINSNS): New macro.
@@ -32,6 +53,7 @@ start-sanitize-m32rx
        * cpux.c,cpux.h,modelx.c,semx.c: Regenerate.
        * m32rx.c (m32rx_model_mark_{busy,unbusy}_reg): New functions.
        * mloopx.in (execute): Update calls to TRACE_INSN_{INIT,FINI}.
+       Fix pc value passed to TRACE_INSN for second parallel insn.
 end-sanitize-m32rx
 
 Thu May  7 02:51:35 1998  Doug Evans  <devans@seba.cygnus.com>
diff --git a/sim/m32r/m32r-sim.h b/sim/m32r/m32r-sim.h
new file mode 100644 (file)
index 0000000..84c9d56
--- /dev/null
@@ -0,0 +1,156 @@
+/* collection of junk waiting time to sort out
+   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of the GNU Simulators.
+
+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 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, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef M32R_SIM_H
+#define M32R_SIM_H
+
+/* Register numbers used in gdb interface.  */
+#define PC_REGNUM      21
+#define ACCL_REGNUM    22
+#define ACCH_REGNUM    23
+\f
+/* Misc. profile data.  */
+
+typedef struct {
+  /* nop insn slot filler count */
+  unsigned int fillnop_count;
+  /* number of parallel insns */
+  unsigned int parallel_count;
+  /* number of short insns, not including parallel ones */
+  unsigned int short_count;
+  /* number of long insns */
+  unsigned int long_count;
+} M32R_MISC_PROFILE;
+
+/* This is invoked by the nop pattern in the .cpu file.  */
+#define PROFILE_COUNT_FILLNOPS(cpu, addr) \
+do { \
+  if (PROFILE_INSN_P (cpu) \
+      && (addr & 3) != 0) \
+    ++ CPU_M32R_MISC_PROFILE (cpu).fillnop_count; \
+} while (0)
+
+/* This is invoked by the execute section of mloop{,x}.in.  */
+#define PROFILE_COUNT_PARINSNS(cpu) \
+do { \
+  if (PROFILE_INSN_P (cpu)) \
+    ++ CPU_M32R_MISC_PROFILE (cpu).parallel_count; \
+} while (0)
+
+/* This is invoked by the execute section of mloop{,x}.in.  */
+#define PROFILE_COUNT_SHORTINSNS(cpu) \
+do { \
+  if (PROFILE_INSN_P (cpu)) \
+    ++ CPU_M32R_MISC_PROFILE (cpu).short_count; \
+} while (0)
+
+/* This is invoked by the execute section of mloop{,x}.in.  */
+#define PROFILE_COUNT_LONGINSNS(cpu) \
+do { \
+  if (PROFILE_INSN_P (cpu)) \
+    ++ CPU_M32R_MISC_PROFILE (cpu).long_count; \
+} while (0)
+\f
+#define GETTWI GETTSI
+#define SETTWI SETTSI
+\f
+/* Additional execution support.  */
+
+/* Result of semantic function is one of
+   - next address, branch only
+   - NEW_PC_SKIP, sc/snc insn
+   - NEW_PC_2, 2 byte non-branch non-sc/snc insn
+   - NEW_PC_4, 4 byte non-branch insn
+   The special values have bit 1 set so it's cheap to distinguish them.  */
+#define NEW_PC_BASE 0xffff0001
+#define NEW_PC_SKIP NEW_PC_BASE
+#define NEW_PC_2 (NEW_PC_BASE + 2)
+#define NEW_PC_4 (NEW_PC_BASE + 4)
+#define NEW_PC_BRANCH_P(addr) (((addr) & 1) == 0)
+
+/* start-sanitize-m32rx */
+/* Modify "next pc" handling to handle parallel execution.  */
+#ifdef WANT_CPU_M32RX
+#undef SEM_NEXT_PC
+#define SEM_NEXT_PC(abuf, len) (NEW_PC_BASE + (len))
+#endif
+/* end-sanitize-m32rx */
+
+/* This macro is emitted by the generator to record branch addresses.  */
+#define BRANCH_NEW_PC(var, addr) \
+do { var = (addr); } while (0)
+\f
+/* Hardware/device support.  */
+
+/* Exception, Interrupt, and Trap addresses */
+#define EIT_SYSBREAK_ADDR      0x10
+#define EIT_RSVD_INSN_ADDR     0x20
+#define EIT_ADDR_EXCP_ADDR     0x30
+#define EIT_TRAP_BASE_ADDR     0x40
+#define EIT_EXTERN_ADDR                0x80
+#define EIT_RESET_ADDR         0x7ffffff0
+#define EIT_WAKEUP_ADDR                0x7ffffff0
+
+/* Special purpose traps.  */
+#define TRAP_SYSCALL   0
+#define TRAP_BREAKPOINT        1
+
+/* Support for the MSPR register (Cache Purge Control Register)
+   and the MCCR register (Cache Control Register) are needed in order for
+   overlays to work correctly with the scache.
+   MSPR no longer exists but is supported for upward compatibility with
+   early overlay support.  */
+
+/* Cache Purge Control (only exists on early versions of chips) */
+#define MSPR_ADDR 0xfffffff7
+#define MSPR_PURGE 1
+
+/* Lock Control Register (not supported) */
+#define MLCR_ADDR 0xfffffff7
+#define MLCR_LM 1
+
+/* Power Management Control Register (not supported) */
+#define MPMR_ADDR 0xfffffffb
+
+/* Cache Control Register */
+#define MCCR_ADDR 0xffffffff
+#define MCCR_CP 0x80
+/* not supported */
+#define MCCR_CM0 2
+#define MCCR_CM1 1
+
+/* Serial device addresses.  */
+#define UART_INCHAR_ADDR       0xff102013
+#define UART_OUTCHAR_ADDR      0xff10200f
+#define UART_STATUS_ADDR       0xff102006
+#define UART_INPUT_EMPTY       0x4
+#define UART_OUTPUT_EMPTY      0x1
+
+/* Start address and length of all device support.  */
+#define M32R_DEVICE_ADDR       0xff000000
+#define M32R_DEVICE_LEN                0x00ffffff
+
+/* sim_core_attach device argument.  */
+extern device m32r_devices;
+
+/* FIXME: Temporary, until device support ready.  */
+struct _device { int foo; };
+
+#endif /* M32R_SIM_H */
index 3f1f3ef..fd9a02f 100644 (file)
@@ -10,12 +10,13 @@ typedef struct _sim_cpu SIM_CPU;
 #include "config.h"
 
 #include "ansidecl.h"
+#include "symcat.h"
 #include "cgen-types.h"
 #include "arch.h"
 #include "sim-basics.h"
 
 /* These must be defined before sim-base.h.  */
-typedef SI sim_cia;
+typedef USI sim_cia;
 #define CIA_GET(cpu)     0 /* FIXME:(CPU_CGEN_HW (cpu)->h_pc) */
 #define CIA_SET(cpu,val) 0 /* FIXME:(CPU_CGEN_HW (cpu)->h_pc = (val)) */
 
@@ -23,12 +24,20 @@ typedef SI sim_cia;
 #define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA)
 #define SIM_ENGINE_RESTART_HOOK(SD, LAST_CPU, CIA)
 
+/* Catch address exceptions.  */
+#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
+m32r_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), \
+                 (TRANSFER), (ERROR))
+
 #include "sim-base.h"
 #include "cgen-sim.h"
 /*#include "cgen-mem.h"*/
 #include "cgen-trace.h"
 #include "cpu-sim.h"
 
+/* Function to catch address exceptions.  */
+extern SIM_CORE_SIGNAL_FN m32r_core_signal;
+
 #ifdef WANT_CPU_M32R
 #include "cpu.h"
 #include "decode.h"
@@ -40,12 +49,8 @@ typedef SI sim_cia;
 #endif
 /* end-sanitize-m32rx */
 #include "cpuall.h"
-
-/* Misc. profile data.  */
-typedef struct {
-  /* nop insn slot filler count */
-  unsigned int fillnop_count;
-} M32R_MISC_PROFILE;
+\f
+/* The _sim_cpu struct.  */
 
 struct _sim_cpu {
   sim_cpu_base base;
@@ -53,11 +58,15 @@ struct _sim_cpu {
   /* Static parts of cgen.  */
   CGEN_CPU cgen_cpu;
 
+  M32R_MISC_PROFILE m32r_misc_profile;
+#define CPU_M32R_MISC_PROFILE(cpu) ((cpu)->m32r_misc_profile)
+
   /* CPU specific parts go here.
      Note that in files that don't need to access these pieces WANT_CPU_FOO
      won't be defined and thus these parts won't appear.  This is ok.
      One has to of course be careful to not take the size of this
-     struct, etc.  */
+     struct and no structure members accessed in non-cpu specific files can
+     go after here.  */
 #if defined (WANT_CPU_M32R)
   M32R_CPU_DATA cpu_data;
 /* start-sanitize-m32rx */
@@ -65,10 +74,9 @@ struct _sim_cpu {
   M32RX_CPU_DATA cpu_data;
 /* end-sanitize-m32rx */
 #endif
-
-  M32R_MISC_PROFILE m32r_misc_profile;
-#define CPU_M32R_MISC_PROFILE(cpu) ((cpu)->m32r_misc_profile)
 };
+\f
+/* The sim_state struct.  */
 
 struct sim_state {
   sim_cpu *cpu;
@@ -78,6 +86,13 @@ struct sim_state {
 
   sim_state_base base;
 };
+\f
+/* Misc.  */
 
 /* Default memory size.  */
 #define M32R_DEFAULT_MEM_SIZE 0x800000 /* 8M */
+
+/* Register access fns.  These look up the current mach and call the
+   appropriate handler.  */
+SI h_gr_get (SIM_CPU *, UINT);
+void h_gr_set (SIM_CPU *, UINT, SI);
diff --git a/sim/m32r/traps.c b/sim/m32r/traps.c
new file mode 100644 (file)
index 0000000..1d250fd
--- /dev/null
@@ -0,0 +1,174 @@
+/* m32r exception, interrupt, and trap (EIT) support
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+This file is part of GDB, the GNU debugger.
+
+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 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, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "sim-main.h"
+#include "targ-vals.h"
+
+/* The semantic code invokes this for illegal (unrecognized) instructions.  */
+
+void
+sim_engine_illegal_insn (SIM_CPU *current_cpu, PCADDR cia)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+
+#if 0
+  if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
+    {
+      h_bsm_set (current_cpu, h_sm_get (current_cpu));
+      h_bie_set (current_cpu, h_ie_get (current_cpu));
+      h_bcond_set (current_cpu, h_cond_get (current_cpu));
+      /* sm not changed */
+      h_ie_set (current_cpu, 0);
+      h_cond_set (current_cpu, 0);
+
+      h_bpc_set (current_cpu, cia);
+
+      sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
+                         EIT_RSVD_INSN_ADDR);
+    }
+  else
+#endif
+    sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
+}
+
+/* Process an address exception.  */
+
+void
+m32r_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
+                 unsigned int map, int nr_bytes, address_word addr,
+                 transfer_type transfer, sim_core_signals sig)
+{
+#if 0
+  if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
+    {
+      h_bsm_set (current_cpu, h_sm_get (current_cpu));
+      h_bie_set (current_cpu, h_ie_get (current_cpu));
+      h_bcond_set (current_cpu, h_cond_get (current_cpu));
+      /* sm not changed */
+      h_ie_set (current_cpu, 0);
+      h_cond_set (current_cpu, 0);
+
+      h_bpc_set (current_cpu, cia);
+
+      sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
+                         EIT_ADDR_EXCP_ADDR);
+    }
+  else
+#endif
+    sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
+                    transfer, sig);
+}
+\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.
+   Preprocessing like saving the various registers has already been done.  */
+
+USI
+a_m32r_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 == TRAP_BREAKPOINT)
+    {
+      /* 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 = EIT_TRAP_BASE_ADDR + num * 4;
+      return new_pc;
+    }
+
+  switch (num)
+    {
+    case TRAP_SYSCALL :
+      {
+       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 TRAP_BREAKPOINT:
+      sim_engine_halt (sd, current_cpu, NULL, NULL_CIA,
+                      sim_stopped, SIM_SIGTRAP);
+      break;
+
+    default :
+      {
+       USI new_pc = EIT_TRAP_BASE_ADDR + num * 4;
+       return new_pc;
+      }
+    }
+
+  /* Fake an "rte" insn.  */
+  return (sim_pc_get (current_cpu) & -4) + 4;
+}