Remove v850ea references
[deliverable/binutils-gdb.git] / sim / v850 / interp.c
CommitLineData
c906108c
SS
1#include "sim-main.h"
2#include "sim-options.h"
3#include "v850_sim.h"
4#include "sim-assert.h"
5#include "itable.h"
6
7#ifdef HAVE_STDLIB_H
8#include <stdlib.h>
9#endif
10
11#ifdef HAVE_STRING_H
12#include <string.h>
13#else
14#ifdef HAVE_STRINGS_H
15#include <strings.h>
16#endif
17#endif
18
19#include "bfd.h"
20
21#ifndef INLINE
22#ifdef __GNUC__
23#define INLINE inline
24#else
25#define INLINE
26#endif
27#endif
28
29static const char * get_insn_name (sim_cpu *, int);
30
31/* For compatibility */
32SIM_DESC simulator;
33
34
35
36/* v850 interrupt model */
37
38enum interrupt_type
39{
40 int_reset,
41 int_nmi,
42 int_intov1,
43 int_intp10,
44 int_intp11,
45 int_intp12,
46 int_intp13,
47 int_intcm4,
48 num_int_types
49};
50
51char *interrupt_names[] = {
52 "reset",
53 "nmi",
54 "intov1",
55 "intp10",
56 "intp11",
57 "intp12",
58 "intp13",
59 "intcm4",
60 NULL
61};
62
63static void
64do_interrupt (sd, data)
65 SIM_DESC sd;
66 void *data;
67{
68 char **interrupt_name = (char**)data;
69 enum interrupt_type inttype;
70 inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
71
72 /* For a hardware reset, drop everything and jump to the start
73 address */
74 if (inttype == int_reset)
75 {
76 PC = 0;
77 PSW = 0x20;
78 ECR = 0;
79 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
80 }
81
82 /* Deliver an NMI when allowed */
83 if (inttype == int_nmi)
84 {
85 if (PSW & PSW_NP)
86 {
87 /* We're already working on an NMI, so this one must wait
88 around until the previous one is done. The processor
89 ignores subsequent NMIs, so we don't need to count them.
90 Just keep re-scheduling a single NMI until it manages to
91 be delivered */
92 if (STATE_CPU (sd, 0)->pending_nmi != NULL)
93 sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
94 STATE_CPU (sd, 0)->pending_nmi =
95 sim_events_schedule (sd, 1, do_interrupt, data);
96 return;
97 }
98 else
99 {
100 /* NMI can be delivered. Do not deschedule pending_nmi as
101 that, if still in the event queue, is a second NMI that
102 needs to be delivered later. */
103 FEPC = PC;
104 FEPSW = PSW;
105 /* Set the FECC part of the ECR. */
106 ECR &= 0x0000ffff;
107 ECR |= 0x10;
108 PSW |= PSW_NP;
109 PSW &= ~PSW_EP;
110 PSW |= PSW_ID;
111 PC = 0x10;
112 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
113 }
114 }
115
116 /* deliver maskable interrupt when allowed */
117 if (inttype > int_nmi && inttype < num_int_types)
118 {
119 if ((PSW & PSW_NP) || (PSW & PSW_ID))
120 {
121 /* Can't deliver this interrupt, reschedule it for later */
122 sim_events_schedule (sd, 1, do_interrupt, data);
123 return;
124 }
125 else
126 {
127 /* save context */
128 EIPC = PC;
129 EIPSW = PSW;
130 /* Disable further interrupts. */
131 PSW |= PSW_ID;
132 /* Indicate that we're doing interrupt not exception processing. */
133 PSW &= ~PSW_EP;
134 /* Clear the EICC part of the ECR, will set below. */
135 ECR &= 0xffff0000;
136 switch (inttype)
137 {
138 case int_intov1:
139 PC = 0x80;
140 ECR |= 0x80;
141 break;
142 case int_intp10:
143 PC = 0x90;
144 ECR |= 0x90;
145 break;
146 case int_intp11:
147 PC = 0xa0;
148 ECR |= 0xa0;
149 break;
150 case int_intp12:
151 PC = 0xb0;
152 ECR |= 0xb0;
153 break;
154 case int_intp13:
155 PC = 0xc0;
156 ECR |= 0xc0;
157 break;
158 case int_intcm4:
159 PC = 0xd0;
160 ECR |= 0xd0;
161 break;
162 default:
163 /* Should never be possible. */
164 sim_engine_abort (sd, NULL, NULL_CIA,
165 "do_interrupt - internal error - bad switch");
166 break;
167 }
168 }
169 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
170 }
171
172 /* some other interrupt? */
173 sim_engine_abort (sd, NULL, NULL_CIA,
174 "do_interrupt - internal error - interrupt %d unknown",
175 inttype);
176}
177
178/* Return name of an insn, used by insn profiling. */
179
180static const char *
181get_insn_name (sim_cpu *cpu, int i)
182{
183 return itable[i].name;
184}
185
186/* These default values correspond to expected usage for the chip. */
187
188uint32 OP[4];
189
190
191SIM_DESC
192sim_open (kind, cb, abfd, argv)
193 SIM_OPEN_KIND kind;
194 host_callback *cb;
195 struct _bfd *abfd;
196 char **argv;
197{
198 SIM_DESC sd = sim_state_alloc (kind, cb);
199 int mach;
200
201 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
202
203 /* for compatibility */
204 simulator = sd;
205
206 /* FIXME: should be better way of setting up interrupts */
207 STATE_WATCHPOINTS (sd)->pc = &(PC);
208 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
209 STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
210 STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
211
212 /* Initialize the mechanism for doing insn profiling. */
213 CPU_INSN_NAME (STATE_CPU (sd, 0)) = get_insn_name;
214 CPU_MAX_INSNS (STATE_CPU (sd, 0)) = nr_itable_entries;
215
216 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
217 return 0;
218
219 /* Allocate core managed memory */
220
221 /* "Mirror" the ROM addresses below 1MB. */
222 sim_do_commandf (sd, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
223 /* Chunk of ram adjacent to rom */
224 sim_do_commandf (sd, "memory region 0x100000,0x%lx", V850_LOW_END-0x100000);
225 /* peripheral I/O region - mirror 1K across 4k (0x1000) */
226 sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
227 /* similarly if in the internal RAM region */
228 sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
229
230 /* getopt will print the error message so we just have to exit if this fails.
231 FIXME: Hmmm... in the case of gdb we need getopt to call
232 print_filtered. */
233 if (sim_parse_args (sd, argv) != SIM_RC_OK)
234 {
235 /* Uninstall the modules to avoid memory leaks,
236 file descriptor leaks, etc. */
237 sim_module_uninstall (sd);
238 return 0;
239 }
240
241 /* check for/establish the a reference program image */
242 if (sim_analyze_program (sd,
243 (STATE_PROG_ARGV (sd) != NULL
244 ? *STATE_PROG_ARGV (sd)
245 : NULL),
246 abfd) != SIM_RC_OK)
247 {
248 sim_module_uninstall (sd);
249 return 0;
250 }
251
252 /* establish any remaining configuration options */
253 if (sim_config (sd) != SIM_RC_OK)
254 {
255 sim_module_uninstall (sd);
256 return 0;
257 }
258
259 if (sim_post_argv_init (sd) != SIM_RC_OK)
260 {
261 /* Uninstall the modules to avoid memory leaks,
262 file descriptor leaks, etc. */
263 sim_module_uninstall (sd);
264 return 0;
265 }
266
267
268 /* determine the machine type */
269 if (STATE_ARCHITECTURE (sd) != NULL
270 && STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850)
271 mach = STATE_ARCHITECTURE (sd)->mach;
272 else
273 mach = bfd_mach_v850; /* default */
274
275 /* set machine specific configuration */
276 switch (mach)
277 {
278 case bfd_mach_v850:
279 case bfd_mach_v850e:
280 STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT
281 | PSW_CY | PSW_OV | PSW_S | PSW_Z);
282 break;
c906108c
SS
283 }
284
285 return sd;
286}
287
288
289void
290sim_close (sd, quitting)
291 SIM_DESC sd;
292 int quitting;
293{
294 sim_module_uninstall (sd);
295}
296
297SIM_RC
298sim_create_inferior (sd, prog_bfd, argv, env)
299 SIM_DESC sd;
300 struct _bfd *prog_bfd;
301 char **argv;
302 char **env;
303{
304 memset (&State, 0, sizeof (State));
305 if (prog_bfd != NULL)
306 PC = bfd_get_start_address (prog_bfd);
c906108c
SS
307 return SIM_RC_OK;
308}
309
310int
311sim_fetch_register (sd, rn, memory, length)
312 SIM_DESC sd;
313 int rn;
314 unsigned char *memory;
315 int length;
316{
317 *(unsigned32*)memory = H2T_4 (State.regs[rn]);
318 return -1;
319}
320
321int
322sim_store_register (sd, rn, memory, length)
323 SIM_DESC sd;
324 int rn;
325 unsigned char *memory;
326 int length;
327{
328 State.regs[rn] = T2H_4 (*(unsigned32*)memory);
329 return -1;
330}
331
332void
333sim_do_command (sd, cmd)
334 SIM_DESC sd;
335 char *cmd;
336{
337 char *mm_cmd = "memory-map";
338 char *int_cmd = "interrupt";
339
340 if (sim_args_command (sd, cmd) != SIM_RC_OK)
341 {
342 if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
343 sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
344 else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
345 sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
346 else
347 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
348 }
349}
This page took 0.23074 seconds and 4 git commands to generate.