]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m68hc11/interp.c
2003-02-27 Andrew Cagney <cagney@redhat.com>
[thirdparty/binutils-gdb.git] / sim / m68hc11 / interp.c
CommitLineData
5abb9efa
SC
1/* interp.c -- Simulator for Motorola 68HC11/68HC12
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
63f36def 3 Written by Stephane Carrez (stcarrez@nerim.fr)
e0709f50
AC
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "sim-main.h"
22#include "sim-assert.h"
23#include "sim-hw.h"
24#include "sim-options.h"
25#include "hw-tree.h"
26#include "hw-device.h"
27#include "hw-ports.h"
28
29#ifndef MONITOR_BASE
30# define MONITOR_BASE (0x0C000)
31# define MONITOR_SIZE (0x04000)
32#endif
33
34static void sim_get_info (SIM_DESC sd, char *cmd);
35
36
37char *interrupt_names[] = {
38 "reset",
39 "nmi",
40 "int",
41 NULL
42};
43
44#ifndef INLINE
45#if defined(__GNUC__) && defined(__OPTIMIZE__)
46#define INLINE __inline__
47#else
48#define INLINE
49#endif
50#endif
51
52struct sim_info_list
53{
54 const char *name;
55 const char *device;
56};
57
81e09ed8 58struct sim_info_list dev_list_68hc11[] = {
e0709f50
AC
59 {"cpu", "/m68hc11"},
60 {"timer", "/m68hc11/m68hc11tim"},
61 {"sio", "/m68hc11/m68hc11sio"},
62 {"spi", "/m68hc11/m68hc11spi"},
63 {"eeprom", "/m68hc11/m68hc11eepr"},
64 {0, 0}
65};
66
81e09ed8
SC
67struct sim_info_list dev_list_68hc12[] = {
68 {"cpu", "/m68hc12"},
69 {"timer", "/m68hc12/m68hc12tim"},
70 {"sio", "/m68hc12/m68hc12sio"},
71 {"spi", "/m68hc12/m68hc12spi"},
72 {"eeprom", "/m68hc12/m68hc12eepr"},
73 {0, 0}
74};
75
76/* Cover function of sim_state_free to free the cpu buffers as well. */
77
78static void
79free_state (SIM_DESC sd)
80{
81 if (STATE_MODULES (sd) != NULL)
82 sim_module_uninstall (sd);
83
84 sim_state_free (sd);
85}
86
e0709f50
AC
87/* Give some information about the simulator. */
88static void
89sim_get_info (SIM_DESC sd, char *cmd)
90{
91 sim_cpu *cpu;
92
81e09ed8 93 cpu = STATE_CPU (sd, 0);
e0709f50
AC
94 if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
95 {
96 int i;
97 struct hw *hw_dev;
81e09ed8
SC
98 struct sim_info_list *dev_list;
99 const struct bfd_arch_info *arch;
100
101 arch = STATE_ARCHITECTURE (sd);
e0709f50
AC
102 cmd++;
103
81e09ed8
SC
104 if (arch->arch == bfd_arch_m68hc11)
105 dev_list = dev_list_68hc11;
106 else
107 dev_list = dev_list_68hc12;
108
e0709f50
AC
109 for (i = 0; dev_list[i].name; i++)
110 if (strcmp (cmd, dev_list[i].name) == 0)
111 break;
112
113 if (dev_list[i].name == 0)
114 {
115 sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
116 sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
117 return;
118 }
119 hw_dev = sim_hw_parse (sd, dev_list[i].device);
120 if (hw_dev == 0)
121 {
122 sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
123 return;
124 }
125 hw_ioctl (hw_dev, 23, 0);
126 return;
127 }
128
e0709f50
AC
129 cpu_info (sd, cpu);
130 interrupts_info (sd, &cpu->cpu_interrupts);
131}
132
133
134void
135sim_board_reset (SIM_DESC sd)
136{
137 struct hw *hw_cpu;
138 sim_cpu *cpu;
81e09ed8
SC
139 const struct bfd_arch_info *arch;
140 const char *cpu_type;
e0709f50
AC
141
142 cpu = STATE_CPU (sd, 0);
81e09ed8
SC
143 arch = STATE_ARCHITECTURE (sd);
144
e0709f50 145 /* hw_cpu = sim_hw_parse (sd, "/"); */
81e09ed8
SC
146 if (arch->arch == bfd_arch_m68hc11)
147 {
148 cpu->cpu_type = CPU_M6811;
149 cpu_type = "/m68hc11";
150 }
151 else
152 {
153 cpu->cpu_type = CPU_M6812;
154 cpu_type = "/m68hc12";
155 }
156
157 hw_cpu = sim_hw_parse (sd, cpu_type);
e0709f50
AC
158 if (hw_cpu == 0)
159 {
81e09ed8 160 sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
e0709f50
AC
161 return;
162 }
163
164 cpu_reset (cpu);
165 hw_port_event (hw_cpu, 3, 0);
166 cpu_restart (cpu);
167}
168
39762100 169static int
81e09ed8
SC
170sim_hw_configure (SIM_DESC sd)
171{
172 const struct bfd_arch_info *arch;
173 struct hw *device_tree;
81e09ed8
SC
174 sim_cpu *cpu;
175
176 arch = STATE_ARCHITECTURE (sd);
177 if (arch == 0)
178 return 0;
179
180 cpu = STATE_CPU (sd, 0);
181 cpu->cpu_configured_arch = arch;
182 device_tree = sim_hw_parse (sd, "/");
183 if (arch->arch == bfd_arch_m68hc11)
184 {
185 cpu->cpu_interpretor = cpu_interp_m6811;
186 if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
187 {
188 /* Allocate core managed memory */
189
190 /* the monitor */
191 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
192 /* MONITOR_BASE, MONITOR_SIZE */
193 0x8000, M6811_RAM_LEVEL, 0x8000);
194 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
195 M6811_RAM_LEVEL);
196 sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
197 }
198
199 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
200 {
201 sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
202 sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
203 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
204 }
205 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
206 {
207 /* M68hc11 Timer configuration. */
208 sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
209 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
827ec39a 210 sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
81e09ed8
SC
211 }
212
213 /* Create the SPI device. */
214 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
215 {
216 sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
217 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
218 }
219 if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
220 {
221 /* M68hc11 persistent ram configuration. */
222 sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
223 sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
224 sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
225 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
226 }
227 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
228 {
229 sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
230 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
231 }
dcceded2
SC
232 sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
233 sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
234 sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
235 sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
827ec39a 236 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
81e09ed8
SC
237 }
238 else
239 {
240 cpu->cpu_interpretor = cpu_interp_m6812;
241 if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
242 {
243 /* Allocate core external memory. */
244 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
7230d809 245 0xC000, M6811_RAM_LEVEL, 0x4000);
81e09ed8
SC
246 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
247 M6811_RAM_LEVEL);
7230d809
SC
248 sim_do_commandf (sd, "memory region 0x01000000@%d,0x100000",
249 M6811_RAM_LEVEL);
81e09ed8
SC
250
251 sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
7230d809 252 sim_hw_parse (sd, "/m68hc12/use_bank 1");
81e09ed8
SC
253 }
254
255 if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
256 {
257 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
258 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
259 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
260 }
81e09ed8
SC
261 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
262 {
263 /* M68hc11 Timer configuration. */
264 sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
265 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
dcceded2 266 sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
81e09ed8
SC
267 }
268
269 /* Create the SPI device. */
270 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
271 {
272 sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
273 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
274 }
275 if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
276 {
277 /* M68hc11 persistent ram configuration. */
278 sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
279 sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
280 sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
281 }
282 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
283 {
284 sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
285 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
286 }
827ec39a 287
dcceded2
SC
288 sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
289 sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
290 sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
291 sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
827ec39a 292 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
81e09ed8 293 }
39762100 294 return 1;
81e09ed8
SC
295}
296
297static int
298sim_prepare_for_program (SIM_DESC sd, struct _bfd* abfd)
299{
300 sim_cpu *cpu;
301
302 cpu = STATE_CPU (sd, 0);
303
39762100
SC
304 if (!sim_hw_configure (sd))
305 return SIM_RC_FAIL;
306
81e09ed8
SC
307 if (abfd != NULL)
308 {
31c7c532 309 asection *s;
81e09ed8 310 cpu->cpu_elf_start = bfd_get_start_address (abfd);
31c7c532
SC
311 /* See if any section sets the reset address */
312 cpu->cpu_use_elf_start = 1;
313 for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next)
314 {
315 if (s->flags & SEC_LOAD)
316 {
317 bfd_size_type size;
318
319 size = bfd_get_section_size_before_reloc (s);
320 if (size > 0)
321 {
322 bfd_vma lma;
323
324 if (STATE_LOAD_AT_LMA_P (sd))
325 lma = bfd_section_lma (abfd, s);
326 else
327 lma = bfd_section_vma (abfd, s);
328
329 if (lma <= 0xFFFE && lma+size >= 0x10000)
330 cpu->cpu_use_elf_start = 0;
331 }
332 }
333 }
81e09ed8
SC
334 }
335
336 /* reset all state information */
337 sim_board_reset (sd);
338
339 return SIM_RC_OK;
340}
341
e0709f50
AC
342SIM_DESC
343sim_open (SIM_OPEN_KIND kind, host_callback *callback,
344 struct _bfd *abfd, char **argv)
345{
e0709f50
AC
346 SIM_DESC sd;
347 sim_cpu *cpu;
e0709f50
AC
348
349 sd = sim_state_alloc (kind, callback);
350 cpu = STATE_CPU (sd, 0);
351
352 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
353
354 /* for compatibility */
355 current_alignment = NONSTRICT_ALIGNMENT;
356 current_target_byte_order = BIG_ENDIAN;
357
358 cpu_initialize (sd, cpu);
359
e0709f50 360 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
81e09ed8
SC
361 {
362 free_state (sd);
363 return 0;
364 }
e0709f50
AC
365
366 /* getopt will print the error message so we just have to exit if this fails.
367 FIXME: Hmmm... in the case of gdb we need getopt to call
368 print_filtered. */
369 if (sim_parse_args (sd, argv) != SIM_RC_OK)
370 {
371 /* Uninstall the modules to avoid memory leaks,
372 file descriptor leaks, etc. */
81e09ed8 373 free_state (sd);
e0709f50
AC
374 return 0;
375 }
376
e0709f50
AC
377 /* Check for/establish the a reference program image. */
378 if (sim_analyze_program (sd,
379 (STATE_PROG_ARGV (sd) != NULL
380 ? *STATE_PROG_ARGV (sd)
381 : NULL), abfd) != SIM_RC_OK)
382 {
81e09ed8 383 free_state (sd);
e0709f50
AC
384 return 0;
385 }
386
387 /* Establish any remaining configuration options. */
388 if (sim_config (sd) != SIM_RC_OK)
389 {
81e09ed8 390 free_state (sd);
e0709f50
AC
391 return 0;
392 }
393
394 if (sim_post_argv_init (sd) != SIM_RC_OK)
395 {
396 /* Uninstall the modules to avoid memory leaks,
397 file descriptor leaks, etc. */
81e09ed8 398 free_state (sd);
e0709f50
AC
399 return 0;
400 }
401
81e09ed8 402 sim_hw_configure (sd);
e0709f50
AC
403
404 /* Fudge our descriptor. */
405 return sd;
406}
407
408
409void
410sim_close (SIM_DESC sd, int quitting)
411{
412 /* shut down modules */
413 sim_module_uninstall (sd);
414
415 /* Ensure that any resources allocated through the callback
416 mechanism are released: */
417 sim_io_shutdown (sd);
418
419 /* FIXME - free SD */
81e09ed8 420 sim_state_free (sd);
e0709f50
AC
421 return;
422}
423
424void
425sim_set_profile (int n)
426{
427}
428
429void
430sim_set_profile_size (int n)
431{
432}
433
434/* Generic implementation of sim_engine_run that works within the
435 sim_engine setjmp/longjmp framework. */
436
437void
438sim_engine_run (SIM_DESC sd,
439 int next_cpu_nr, /* ignore */
440 int nr_cpus, /* ignore */
441 int siggnal) /* ignore */
442{
443 sim_cpu *cpu;
444
445 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
446 cpu = STATE_CPU (sd, 0);
447 while (1)
448 {
449 cpu_single_step (cpu);
450
451 /* process any events */
452 if (sim_events_tickn (sd, cpu->cpu_current_cycle))
453 {
454 sim_events_process (sd);
455 }
456 }
457}
458
459int
460sim_trace (SIM_DESC sd)
461{
462 sim_resume (sd, 0, 0);
463 return 1;
464}
465
466void
467sim_info (SIM_DESC sd, int verbose)
468{
81e09ed8
SC
469 const char *cpu_type;
470 const struct bfd_arch_info *arch;
471
00d0c012
SC
472 /* Nothing to do if there is no verbose flag set. */
473 if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
474 return;
475
81e09ed8
SC
476 arch = STATE_ARCHITECTURE (sd);
477 if (arch->arch == bfd_arch_m68hc11)
478 cpu_type = "68HC11";
479 else
480 cpu_type = "68HC12";
481
e0709f50 482 sim_io_eprintf (sd, "Simulator info:\n");
81e09ed8 483 sim_io_eprintf (sd, " CPU Motorola %s\n", cpu_type);
e0709f50
AC
484 sim_get_info (sd, 0);
485 sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
486}
487
488SIM_RC
489sim_create_inferior (SIM_DESC sd, struct _bfd *abfd,
490 char **argv, char **env)
491{
81e09ed8 492 return sim_prepare_for_program (sd, abfd);
e0709f50
AC
493}
494
495
496void
497sim_set_callbacks (host_callback *p)
498{
499 /* m6811_callback = p; */
500}
501
502
503int
504sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
505{
506 sim_cpu *cpu;
507 uint16 val;
63f36def 508 int size = 2;
e0709f50
AC
509
510 cpu = STATE_CPU (sd, 0);
511 switch (rn)
512 {
513 case A_REGNUM:
514 val = cpu_get_a (cpu);
63f36def 515 size = 1;
e0709f50
AC
516 break;
517
518 case B_REGNUM:
519 val = cpu_get_b (cpu);
63f36def 520 size = 1;
e0709f50
AC
521 break;
522
523 case D_REGNUM:
524 val = cpu_get_d (cpu);
525 break;
526
527 case X_REGNUM:
528 val = cpu_get_x (cpu);
529 break;
530
531 case Y_REGNUM:
532 val = cpu_get_y (cpu);
533 break;
534
535 case SP_REGNUM:
536 val = cpu_get_sp (cpu);
537 break;
538
539 case PC_REGNUM:
540 val = cpu_get_pc (cpu);
541 break;
542
543 case PSW_REGNUM:
544 val = cpu_get_ccr (cpu);
63f36def
SC
545 size = 1;
546 break;
547
548 case PAGE_REGNUM:
549 val = cpu_get_page (cpu);
550 size = 1;
e0709f50
AC
551 break;
552
e0709f50 553 default:
9830501b 554 val = 0;
e0709f50
AC
555 break;
556 }
557 memory[0] = val >> 8;
558 memory[1] = val & 0x0FF;
63f36def 559 return size;
e0709f50
AC
560}
561
562int
563sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
564{
565 uint16 val;
566 sim_cpu *cpu;
567
568 cpu = STATE_CPU (sd, 0);
569
570 val = *memory++;
571 if (length == 2)
572 val = (val << 8) | *memory;
573
574 switch (rn)
575 {
576 case D_REGNUM:
577 cpu_set_d (cpu, val);
578 break;
579
580 case A_REGNUM:
581 cpu_set_a (cpu, val);
63f36def 582 return 1;
e0709f50
AC
583
584 case B_REGNUM:
585 cpu_set_b (cpu, val);
63f36def 586 return 1;
e0709f50
AC
587
588 case X_REGNUM:
589 cpu_set_x (cpu, val);
590 break;
591
592 case Y_REGNUM:
593 cpu_set_y (cpu, val);
594 break;
595
596 case SP_REGNUM:
597 cpu_set_sp (cpu, val);
598 break;
599
600 case PC_REGNUM:
601 cpu_set_pc (cpu, val);
602 break;
603
604 case PSW_REGNUM:
605 cpu_set_ccr (cpu, val);
63f36def
SC
606 return 1;
607
608 case PAGE_REGNUM:
609 cpu_set_page (cpu, val);
610 return 1;
e0709f50 611
e0709f50 612 default:
e0709f50
AC
613 break;
614 }
615
616 return 2;
617}
618
619void
620sim_size (int s)
621{
622 ;
623}
624
625void
626sim_do_command (SIM_DESC sd, char *cmd)
627{
628 char *mm_cmd = "memory-map";
629 char *int_cmd = "interrupt";
81e09ed8 630 sim_cpu *cpu;
e0709f50 631
81e09ed8 632 cpu = STATE_CPU (sd, 0);
e0709f50
AC
633 /* Commands available from GDB: */
634 if (sim_args_command (sd, cmd) != SIM_RC_OK)
635 {
636 if (strncmp (cmd, "info", sizeof ("info") - 1) == 0)
637 sim_get_info (sd, &cmd[4]);
e0709f50
AC
638 else if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
639 sim_io_eprintf (sd,
640 "`memory-map' command replaced by `sim memory'\n");
641 else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
642 sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
643 else
644 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
645 }
81e09ed8
SC
646
647 /* If the architecture changed, re-configure. */
648 if (STATE_ARCHITECTURE (sd) != cpu->cpu_configured_arch)
649 sim_hw_configure (sd);
e0709f50 650}
00d0c012
SC
651
652/* Halt the simulator after just one instruction */
653
654static void
655has_stepped (SIM_DESC sd,
656 void *data)
657{
658 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
659 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
660}
661
662
663/* Generic resume - assumes the existance of sim_engine_run */
664
665void
666sim_resume (SIM_DESC sd,
667 int step,
668 int siggnal)
669{
670 sim_engine *engine = STATE_ENGINE (sd);
671 jmp_buf buf;
672 int jmpval;
673
674 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
675
676 /* we only want to be single stepping the simulator once */
677 if (engine->stepper != NULL)
678 {
679 sim_events_deschedule (sd, engine->stepper);
680 engine->stepper = NULL;
681 }
682 sim_module_resume (sd);
683
684 /* run/resume the simulator */
685 engine->jmpbuf = &buf;
686 jmpval = setjmp (buf);
687 if (jmpval == sim_engine_start_jmpval
688 || jmpval == sim_engine_restart_jmpval)
689 {
690 int last_cpu_nr = sim_engine_last_cpu_nr (sd);
691 int next_cpu_nr = sim_engine_next_cpu_nr (sd);
692 int nr_cpus = sim_engine_nr_cpus (sd);
693
694 sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
695 if (next_cpu_nr >= nr_cpus)
696 next_cpu_nr = 0;
697
698 /* Only deliver the siggnal ]sic] the first time through - don't
699 re-deliver any siggnal during a restart. */
700 if (jmpval == sim_engine_restart_jmpval)
701 siggnal = 0;
702
703 /* Install the stepping event after having processed some
704 pending events. This is necessary for HC11/HC12 simulator
705 because the tick counter is incremented by the number of cycles
706 the instruction took. Some pending ticks to process can still
707 be recorded internally by the simulator and sim_events_preprocess
708 will handle them. If the stepping event is inserted before,
709 these pending ticks will raise the event and the simulator will
710 stop without having executed any instruction. */
711 if (step)
712 engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
713
714#ifdef SIM_CPU_EXCEPTION_RESUME
715 {
716 sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
717 SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
718 }
719#endif
720
721 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
722 }
723 engine->jmpbuf = NULL;
724
725 sim_module_suspend (sd);
726}