OSDN Git Service

570fc95eeba7f1649f429a1e6e450865c25acf09
[pf3gnuchains/pf3gnuchains4x.git] / sim / i960 / traps.c
1 /* i960 exception, interrupt, and trap (EIT) support
2    Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4
5 This file is part of GDB, the GNU debugger.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "sim-main.h"
22 #include "targ-vals.h"
23
24 /* The semantic code invokes this for illegal (unrecognized) instructions.  */
25
26 SEM_PC
27 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
28 {
29   SIM_DESC sd = CPU_STATE (current_cpu);
30
31 #if 0
32   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
33     {
34       h_bsm_set (current_cpu, h_sm_get (current_cpu));
35       h_bie_set (current_cpu, h_ie_get (current_cpu));
36       h_bcond_set (current_cpu, h_cond_get (current_cpu));
37       /* sm not changed */
38       h_ie_set (current_cpu, 0);
39       h_cond_set (current_cpu, 0);
40
41       h_bpc_set (current_cpu, cia);
42
43       sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
44                           EIT_RSVD_INSN_ADDR);
45     }
46   else
47 #endif
48     sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
49   return vpc;
50 }
51
52 /* Process an address exception.  */
53
54 void
55 i960_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
56                   unsigned int map, int nr_bytes, address_word addr,
57                   transfer_type transfer, sim_core_signals sig)
58 {
59 #if 0
60   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
61     {
62       h_bsm_set (current_cpu, h_sm_get (current_cpu));
63       h_bie_set (current_cpu, h_ie_get (current_cpu));
64       h_bcond_set (current_cpu, h_cond_get (current_cpu));
65       /* sm not changed */
66       h_ie_set (current_cpu, 0);
67       h_cond_set (current_cpu, 0);
68
69       h_bpc_set (current_cpu, cia);
70
71       sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
72                           EIT_ADDR_EXCP_ADDR);
73     }
74   else
75 #endif
76     sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
77                      transfer, sig);
78 }
79 \f
80 /* Read/write functions for system call interface.  */
81
82 static int
83 syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
84                   unsigned long taddr, char *buf, int bytes)
85 {
86   SIM_DESC sd = (SIM_DESC) sc->p1;
87   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
88
89   return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
90 }
91
92 static int
93 syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
94                    unsigned long taddr, const char *buf, int bytes)
95 {
96   SIM_DESC sd = (SIM_DESC) sc->p1;
97   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
98
99   return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
100 }
101
102 /* Trap support.
103    The result is the pc address to continue at.
104    Preprocessing like saving the various registers has already been done.  */
105
106 USI
107 i960_trap (SIM_CPU *current_cpu, PCADDR pc, int num)
108 {
109   SIM_DESC sd = CPU_STATE (current_cpu);
110   host_callback *cb = STATE_CALLBACK (sd);
111
112 #ifdef SIM_HAVE_BREAKPOINTS
113   /* Check for breakpoints "owned" by the simulator first, regardless
114      of --environment.  */
115   if (num == TRAP_BREAKPOINT)
116     {
117       /* First try sim-break.c.  If it's a breakpoint the simulator "owns"
118          it doesn't return.  Otherwise it returns and let's us try.  */
119       sim_handle_breakpoint (sd, current_cpu, pc);
120       /* Fall through.  */
121     }
122 #endif
123
124 #if 0
125   /* ??? wilson, don't know what this does.  */
126   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
127     {
128       /* The new pc is the trap vector entry.
129          We assume there's a branch there to some handler.  */
130       USI new_pc = EIT_TRAP_BASE_ADDR + num * 4;
131       return new_pc;
132     }
133 #endif
134
135   switch (num)
136     {
137     default:
138     case TRAP_SYSCALL :
139       {
140         CB_SYSCALL s;
141
142         CB_SYSCALL_INIT (&s);
143         s.func = num;
144         s.arg1 = a_i960_h_gr_get (current_cpu, 16);
145         s.arg2 = a_i960_h_gr_get (current_cpu, 17);
146         s.arg3 = a_i960_h_gr_get (current_cpu, 18);
147
148         if (s.func == TARGET_SYS_exit)
149           {
150             sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
151           }
152
153         s.p1 = (PTR) sd;
154         s.p2 = (PTR) current_cpu;
155         s.read_mem = syscall_read_mem;
156         s.write_mem = syscall_write_mem;
157         cb_syscall (cb, &s);
158         /* ??? This stuff is probably wrong, but libgloss doesn't look at
159            these values, so it shouldn't matter.  */
160         a_i960_h_gr_set (current_cpu, 18, s.errcode);
161         a_i960_h_gr_set (current_cpu, 16, s.result);
162         a_i960_h_gr_set (current_cpu, 17, s.result2);
163         break;
164       }
165
166     case TRAP_BREAKPOINT:
167       sim_engine_halt (sd, current_cpu, NULL, NULL_CIA,
168                        sim_stopped, SIM_SIGTRAP);
169       break;
170
171 #if 0
172       /* ??? wilson, don't know what this does.  */
173     default :
174       {
175         USI new_pc = EIT_TRAP_BASE_ADDR + num * 4;
176         return new_pc;
177       }
178 #endif
179     }
180
181   /* Fake an "rte" insn.  */
182   /* FIXME: Should duplicate all of rte processing.  */
183   return (pc & -4) + 4;
184 }
185
186 /* Breakpoint support.
187    The result is the pc address to continue at.  */
188 /* ??? This is an editted copy of the above.  */
189
190 USI
191 i960_breakpoint (SIM_CPU *current_cpu, PCADDR pc)
192 {
193   SIM_DESC sd = CPU_STATE (current_cpu);
194   host_callback *cb = STATE_CALLBACK (sd);
195
196 #ifdef SIM_HAVE_BREAKPOINTS
197   /* Check for breakpoints "owned" by the simulator first, regardless
198      of --environment.  */
199   if (num == TRAP_BREAKPOINT)
200     {
201       /* First try sim-break.c.  If it's a breakpoint the simulator "owns"
202          it doesn't return.  Otherwise it returns and let's us try.  */
203       sim_handle_breakpoint (sd, current_cpu, pc);
204       /* Fall through.  */
205     }
206 #endif
207
208   sim_engine_halt (sd, current_cpu, NULL, NULL_CIA,
209                    sim_stopped, SIM_SIGTRAP);
210
211   /* Fake an "rte" insn.  */
212   /* FIXME: Should duplicate all of rte processing.  */
213   return (pc & -4) + 4;
214 }