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