]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/m68hc11/interp.c
sim: m68hc11/mips/mn10300/v850: add basic sim_pc_get
[thirdparty/binutils-gdb.git] / sim / m68hc11 / interp.c
1 /* interp.c -- Simulator for Motorola 68HC11/68HC12
2 Copyright (C) 1999-2015 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
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 3 of the License, or
10 (at your option) 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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "sim-main.h"
21 #include "sim-assert.h"
22 #include "sim-hw.h"
23 #include "sim-options.h"
24 #include "hw-tree.h"
25 #include "hw-device.h"
26 #include "hw-ports.h"
27 #include "elf32-m68hc1x.h"
28
29 #ifndef MONITOR_BASE
30 # define MONITOR_BASE (0x0C000)
31 # define MONITOR_SIZE (0x04000)
32 #endif
33
34 static void sim_get_info (SIM_DESC sd, char *cmd);
35
36
37 char *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
52 struct sim_info_list
53 {
54 const char *name;
55 const char *device;
56 };
57
58 struct sim_info_list dev_list_68hc11[] = {
59 {"cpu", "/m68hc11"},
60 {"timer", "/m68hc11/m68hc11tim"},
61 {"sio", "/m68hc11/m68hc11sio"},
62 {"spi", "/m68hc11/m68hc11spi"},
63 {"eeprom", "/m68hc11/m68hc11eepr"},
64 {0, 0}
65 };
66
67 struct 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
78 static void
79 free_state (SIM_DESC sd)
80 {
81 if (STATE_MODULES (sd) != NULL)
82 sim_module_uninstall (sd);
83
84 sim_state_free (sd);
85 }
86
87 /* Give some information about the simulator. */
88 static void
89 sim_get_info (SIM_DESC sd, char *cmd)
90 {
91 sim_cpu *cpu;
92
93 cpu = STATE_CPU (sd, 0);
94 if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
95 {
96 int i;
97 struct hw *hw_dev;
98 struct sim_info_list *dev_list;
99 const struct bfd_arch_info *arch;
100
101 arch = STATE_ARCHITECTURE (sd);
102 cmd++;
103
104 if (arch->arch == bfd_arch_m68hc11)
105 dev_list = dev_list_68hc11;
106 else
107 dev_list = dev_list_68hc12;
108
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
129 cpu_info (sd, cpu);
130 interrupts_info (sd, &cpu->cpu_interrupts);
131 }
132
133
134 void
135 sim_board_reset (SIM_DESC sd)
136 {
137 struct hw *hw_cpu;
138 sim_cpu *cpu;
139 const struct bfd_arch_info *arch;
140 const char *cpu_type;
141
142 cpu = STATE_CPU (sd, 0);
143 arch = STATE_ARCHITECTURE (sd);
144
145 /* hw_cpu = sim_hw_parse (sd, "/"); */
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);
158 if (hw_cpu == 0)
159 {
160 sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
161 return;
162 }
163
164 cpu_reset (cpu);
165 hw_port_event (hw_cpu, 3, 0);
166 cpu_restart (cpu);
167 }
168
169 static int
170 sim_hw_configure (SIM_DESC sd)
171 {
172 const struct bfd_arch_info *arch;
173 struct hw *device_tree;
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 if (cpu->bank_start < cpu->bank_end)
198 {
199 sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
200 cpu->bank_virtual, M6811_RAM_LEVEL);
201 sim_hw_parse (sd, "/m68hc11/use_bank 1");
202 }
203 }
204 if (cpu->cpu_start_mode)
205 {
206 sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
207 }
208 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
209 {
210 sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
211 sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
212 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
213 }
214 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
215 {
216 /* M68hc11 Timer configuration. */
217 sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
218 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
219 sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
220 }
221
222 /* Create the SPI device. */
223 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
224 {
225 sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
226 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
227 }
228 if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
229 {
230 /* M68hc11 persistent ram configuration. */
231 sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
232 sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
233 sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
234 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
235 }
236 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
237 {
238 sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
239 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
240 }
241 sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
242 sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
243 sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
244 sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
245 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
246 }
247 else
248 {
249 cpu->cpu_interpretor = cpu_interp_m6812;
250 if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
251 {
252 /* Allocate core external memory. */
253 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
254 0x8000, M6811_RAM_LEVEL, 0x8000);
255 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
256 M6811_RAM_LEVEL);
257 if (cpu->bank_start < cpu->bank_end)
258 {
259 sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
260 cpu->bank_virtual, M6811_RAM_LEVEL);
261 sim_hw_parse (sd, "/m68hc12/use_bank 1");
262 }
263 sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
264 }
265
266 if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
267 {
268 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
269 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
270 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
271 }
272 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
273 {
274 /* M68hc11 Timer configuration. */
275 sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
276 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
277 sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
278 }
279
280 /* Create the SPI device. */
281 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
282 {
283 sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
284 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
285 }
286 if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
287 {
288 /* M68hc11 persistent ram configuration. */
289 sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
290 sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
291 sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
292 }
293 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
294 {
295 sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
296 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
297 }
298
299 sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
300 sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
301 sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
302 sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
303 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
304 }
305 return 1;
306 }
307
308 /* Get the memory bank parameters by looking at the global symbols
309 defined by the linker. */
310 static int
311 sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
312 {
313 sim_cpu *cpu;
314 long symsize;
315 long symbol_count, i;
316 unsigned size;
317 asymbol** asymbols;
318 asymbol** current;
319
320 cpu = STATE_CPU (sd, 0);
321
322 symsize = bfd_get_symtab_upper_bound (abfd);
323 if (symsize < 0)
324 {
325 sim_io_eprintf (sd, "Cannot read symbols of program");
326 return 0;
327 }
328 asymbols = (asymbol **) xmalloc (symsize);
329 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
330 if (symbol_count < 0)
331 {
332 sim_io_eprintf (sd, "Cannot read symbols of program");
333 return 0;
334 }
335
336 size = 0;
337 for (i = 0, current = asymbols; i < symbol_count; i++, current++)
338 {
339 const char* name = bfd_asymbol_name (*current);
340
341 if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
342 {
343 cpu->bank_start = bfd_asymbol_value (*current);
344 }
345 else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
346 {
347 size = bfd_asymbol_value (*current);
348 }
349 else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
350 {
351 cpu->bank_virtual = bfd_asymbol_value (*current);
352 }
353 }
354 free (asymbols);
355
356 cpu->bank_end = cpu->bank_start + size;
357 cpu->bank_shift = 0;
358 for (; size > 1; size >>= 1)
359 cpu->bank_shift++;
360
361 return 0;
362 }
363
364 static int
365 sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
366 {
367 sim_cpu *cpu;
368 int elf_flags = 0;
369
370 cpu = STATE_CPU (sd, 0);
371
372 if (abfd != NULL)
373 {
374 asection *s;
375
376 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
377 elf_flags = elf_elfheader (abfd)->e_flags;
378
379 cpu->cpu_elf_start = bfd_get_start_address (abfd);
380 /* See if any section sets the reset address */
381 cpu->cpu_use_elf_start = 1;
382 for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next)
383 {
384 if (s->flags & SEC_LOAD)
385 {
386 bfd_size_type size;
387
388 size = bfd_get_section_size (s);
389 if (size > 0)
390 {
391 bfd_vma lma;
392
393 if (STATE_LOAD_AT_LMA_P (sd))
394 lma = bfd_section_lma (abfd, s);
395 else
396 lma = bfd_section_vma (abfd, s);
397
398 if (lma <= 0xFFFE && lma+size >= 0x10000)
399 cpu->cpu_use_elf_start = 0;
400 }
401 }
402 }
403
404 if (elf_flags & E_M68HC12_BANKS)
405 {
406 if (sim_get_bank_parameters (sd, abfd) != 0)
407 sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
408 }
409 }
410
411 if (!sim_hw_configure (sd))
412 return SIM_RC_FAIL;
413
414 /* reset all state information */
415 sim_board_reset (sd);
416
417 return SIM_RC_OK;
418 }
419
420 SIM_DESC
421 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
422 bfd *abfd, char **argv)
423 {
424 SIM_DESC sd;
425 sim_cpu *cpu;
426
427 sd = sim_state_alloc (kind, callback);
428 cpu = STATE_CPU (sd, 0);
429
430 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
431
432 /* for compatibility */
433 current_alignment = NONSTRICT_ALIGNMENT;
434 current_target_byte_order = BIG_ENDIAN;
435
436 cpu_initialize (sd, cpu);
437
438 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
439 {
440 free_state (sd);
441 return 0;
442 }
443
444 /* getopt will print the error message so we just have to exit if this fails.
445 FIXME: Hmmm... in the case of gdb we need getopt to call
446 print_filtered. */
447 if (sim_parse_args (sd, argv) != SIM_RC_OK)
448 {
449 /* Uninstall the modules to avoid memory leaks,
450 file descriptor leaks, etc. */
451 free_state (sd);
452 return 0;
453 }
454
455 /* Check for/establish the a reference program image. */
456 if (sim_analyze_program (sd,
457 (STATE_PROG_ARGV (sd) != NULL
458 ? *STATE_PROG_ARGV (sd)
459 : NULL), abfd) != SIM_RC_OK)
460 {
461 free_state (sd);
462 return 0;
463 }
464
465 /* Establish any remaining configuration options. */
466 if (sim_config (sd) != SIM_RC_OK)
467 {
468 free_state (sd);
469 return 0;
470 }
471
472 if (sim_post_argv_init (sd) != SIM_RC_OK)
473 {
474 /* Uninstall the modules to avoid memory leaks,
475 file descriptor leaks, etc. */
476 free_state (sd);
477 return 0;
478 }
479 if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
480 {
481 free_state (sd);
482 return 0;
483 }
484
485 /* Fudge our descriptor. */
486 return sd;
487 }
488
489
490 void
491 sim_close (SIM_DESC sd, int quitting)
492 {
493 /* shut down modules */
494 sim_module_uninstall (sd);
495
496 /* Ensure that any resources allocated through the callback
497 mechanism are released: */
498 sim_io_shutdown (sd);
499
500 /* FIXME - free SD */
501 sim_state_free (sd);
502 return;
503 }
504
505 /* Generic implementation of sim_engine_run that works within the
506 sim_engine setjmp/longjmp framework. */
507
508 void
509 sim_engine_run (SIM_DESC sd,
510 int next_cpu_nr, /* ignore */
511 int nr_cpus, /* ignore */
512 int siggnal) /* ignore */
513 {
514 sim_cpu *cpu;
515
516 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
517 cpu = STATE_CPU (sd, 0);
518 while (1)
519 {
520 cpu_single_step (cpu);
521
522 /* process any events */
523 if (sim_events_tickn (sd, cpu->cpu_current_cycle))
524 {
525 sim_events_process (sd);
526 }
527 }
528 }
529
530 void
531 sim_info (SIM_DESC sd, int verbose)
532 {
533 const char *cpu_type;
534 const struct bfd_arch_info *arch;
535
536 /* Nothing to do if there is no verbose flag set. */
537 if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
538 return;
539
540 arch = STATE_ARCHITECTURE (sd);
541 if (arch->arch == bfd_arch_m68hc11)
542 cpu_type = "68HC11";
543 else
544 cpu_type = "68HC12";
545
546 sim_io_eprintf (sd, "Simulator info:\n");
547 sim_io_eprintf (sd, " CPU Motorola %s\n", cpu_type);
548 sim_get_info (sd, 0);
549 sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
550 }
551
552 SIM_RC
553 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
554 char **argv, char **env)
555 {
556 return sim_prepare_for_program (sd, abfd);
557 }
558
559 int
560 sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
561 {
562 sim_cpu *cpu;
563 uint16 val;
564 int size = 2;
565
566 cpu = STATE_CPU (sd, 0);
567 switch (rn)
568 {
569 case A_REGNUM:
570 val = cpu_get_a (cpu);
571 size = 1;
572 break;
573
574 case B_REGNUM:
575 val = cpu_get_b (cpu);
576 size = 1;
577 break;
578
579 case D_REGNUM:
580 val = cpu_get_d (cpu);
581 break;
582
583 case X_REGNUM:
584 val = cpu_get_x (cpu);
585 break;
586
587 case Y_REGNUM:
588 val = cpu_get_y (cpu);
589 break;
590
591 case SP_REGNUM:
592 val = cpu_get_sp (cpu);
593 break;
594
595 case PC_REGNUM:
596 val = cpu_get_pc (cpu);
597 break;
598
599 case PSW_REGNUM:
600 val = cpu_get_ccr (cpu);
601 size = 1;
602 break;
603
604 case PAGE_REGNUM:
605 val = cpu_get_page (cpu);
606 size = 1;
607 break;
608
609 default:
610 val = 0;
611 break;
612 }
613 if (size == 1)
614 {
615 memory[0] = val;
616 }
617 else
618 {
619 memory[0] = val >> 8;
620 memory[1] = val & 0x0FF;
621 }
622 return size;
623 }
624
625 int
626 sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
627 {
628 uint16 val;
629 sim_cpu *cpu;
630
631 cpu = STATE_CPU (sd, 0);
632
633 val = *memory++;
634 if (length == 2)
635 val = (val << 8) | *memory;
636
637 switch (rn)
638 {
639 case D_REGNUM:
640 cpu_set_d (cpu, val);
641 break;
642
643 case A_REGNUM:
644 cpu_set_a (cpu, val);
645 return 1;
646
647 case B_REGNUM:
648 cpu_set_b (cpu, val);
649 return 1;
650
651 case X_REGNUM:
652 cpu_set_x (cpu, val);
653 break;
654
655 case Y_REGNUM:
656 cpu_set_y (cpu, val);
657 break;
658
659 case SP_REGNUM:
660 cpu_set_sp (cpu, val);
661 break;
662
663 case PC_REGNUM:
664 cpu_set_pc (cpu, val);
665 break;
666
667 case PSW_REGNUM:
668 cpu_set_ccr (cpu, val);
669 return 1;
670
671 case PAGE_REGNUM:
672 cpu_set_page (cpu, val);
673 return 1;
674
675 default:
676 break;
677 }
678
679 return 2;
680 }
681
682 sim_cia
683 sim_pc_get (sim_cpu *cpu)
684 {
685 return CIA_GET (cpu);
686 }
687
688 /* Halt the simulator after just one instruction */
689
690 static void
691 has_stepped (SIM_DESC sd,
692 void *data)
693 {
694 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
695 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
696 }
697
698
699 /* Generic resume - assumes the existance of sim_engine_run */
700
701 void
702 sim_resume (SIM_DESC sd,
703 int step,
704 int siggnal)
705 {
706 sim_engine *engine = STATE_ENGINE (sd);
707 jmp_buf buf;
708 int jmpval;
709
710 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
711
712 /* we only want to be single stepping the simulator once */
713 if (engine->stepper != NULL)
714 {
715 sim_events_deschedule (sd, engine->stepper);
716 engine->stepper = NULL;
717 }
718 sim_module_resume (sd);
719
720 /* run/resume the simulator */
721 engine->jmpbuf = &buf;
722 jmpval = setjmp (buf);
723 if (jmpval == sim_engine_start_jmpval
724 || jmpval == sim_engine_restart_jmpval)
725 {
726 int last_cpu_nr = sim_engine_last_cpu_nr (sd);
727 int next_cpu_nr = sim_engine_next_cpu_nr (sd);
728 int nr_cpus = sim_engine_nr_cpus (sd);
729
730 sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
731 if (next_cpu_nr >= nr_cpus)
732 next_cpu_nr = 0;
733
734 /* Only deliver the siggnal ]sic] the first time through - don't
735 re-deliver any siggnal during a restart. */
736 if (jmpval == sim_engine_restart_jmpval)
737 siggnal = 0;
738
739 /* Install the stepping event after having processed some
740 pending events. This is necessary for HC11/HC12 simulator
741 because the tick counter is incremented by the number of cycles
742 the instruction took. Some pending ticks to process can still
743 be recorded internally by the simulator and sim_events_preprocess
744 will handle them. If the stepping event is inserted before,
745 these pending ticks will raise the event and the simulator will
746 stop without having executed any instruction. */
747 if (step)
748 engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
749
750 #ifdef SIM_CPU_EXCEPTION_RESUME
751 {
752 sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
753 SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
754 }
755 #endif
756
757 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
758 }
759 engine->jmpbuf = NULL;
760
761 sim_module_suspend (sd);
762 }