diff options
Diffstat (limited to 'sim/m32r')
-rw-r--r-- | sim/m32r/.Sanitize | 1 | ||||
-rw-r--r-- | sim/m32r/ChangeLog | 22 | ||||
-rw-r--r-- | sim/m32r/m32r-sim.h | 156 | ||||
-rw-r--r-- | sim/m32r/sim-main.h | 37 | ||||
-rw-r--r-- | sim/m32r/traps.c | 174 |
5 files changed, 379 insertions, 11 deletions
diff --git a/sim/m32r/.Sanitize b/sim/m32r/.Sanitize index f0e0ffa..a92df7a 100644 --- a/sim/m32r/.Sanitize +++ b/sim/m32r/.Sanitize @@ -57,6 +57,7 @@ sem.c sim-if.c sim-main.h tconfig.in +traps.c Things-to-lose: diff --git a/sim/m32r/ChangeLog b/sim/m32r/ChangeLog index 5465fd5..1f6167a 100644 --- a/sim/m32r/ChangeLog +++ b/sim/m32r/ChangeLog @@ -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 index 0000000..84c9d56 --- /dev/null +++ b/sim/m32r/m32r-sim.h @@ -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 + +/* 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) + +#define GETTWI GETTSI +#define SETTWI SETTSI + +/* 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) + +/* 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 */ diff --git a/sim/m32r/sim-main.h b/sim/m32r/sim-main.h index 3f1f3ef..fd9a02f 100644 --- a/sim/m32r/sim-main.h +++ b/sim/m32r/sim-main.h @@ -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; + +/* 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) }; + +/* The sim_state struct. */ struct sim_state { sim_cpu *cpu; @@ -78,6 +86,13 @@ struct sim_state { sim_state_base base; }; + +/* 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 index 0000000..1d250fd --- /dev/null +++ b/sim/m32r/traps.c @@ -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); +} + +/* 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; +} |