sim: fix the PKGVERSION define
[external/binutils.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 static sim_cia
421 m68hc11_pc_get (sim_cpu *cpu)
422 {
423   return cpu_get_pc (cpu);
424 }
425
426 static void
427 m68hc11_pc_set (sim_cpu *cpu, sim_cia pc)
428 {
429   cpu_set_pc (cpu, pc);
430 }
431
432 SIM_DESC
433 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
434           bfd *abfd, char **argv)
435 {
436   int i;
437   SIM_DESC sd;
438   sim_cpu *cpu;
439
440   sd = sim_state_alloc (kind, callback);
441
442   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
443
444   /* The cpu data is kept in a separately allocated chunk of memory.  */
445   if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
446     {
447       free_state (sd);
448       return 0;
449     }
450
451   cpu = STATE_CPU (sd, 0);
452
453   /* for compatibility */
454   current_alignment = NONSTRICT_ALIGNMENT;
455   current_target_byte_order = BIG_ENDIAN;
456
457   cpu_initialize (sd, cpu);
458
459   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
460     {
461       free_state (sd);
462       return 0;
463     }
464
465   /* getopt will print the error message so we just have to exit if this fails.
466      FIXME: Hmmm...  in the case of gdb we need getopt to call
467      print_filtered.  */
468   if (sim_parse_args (sd, argv) != SIM_RC_OK)
469     {
470       /* Uninstall the modules to avoid memory leaks,
471          file descriptor leaks, etc.  */
472       free_state (sd);
473       return 0;
474     }
475
476   /* Check for/establish the a reference program image.  */
477   if (sim_analyze_program (sd,
478                            (STATE_PROG_ARGV (sd) != NULL
479                             ? *STATE_PROG_ARGV (sd)
480                             : NULL), abfd) != SIM_RC_OK)
481     {
482       free_state (sd);
483       return 0;
484     }
485
486   /* Establish any remaining configuration options.  */
487   if (sim_config (sd) != SIM_RC_OK)
488     {
489       free_state (sd);
490       return 0;
491     }
492
493   if (sim_post_argv_init (sd) != SIM_RC_OK)
494     {
495       /* Uninstall the modules to avoid memory leaks,
496          file descriptor leaks, etc.  */
497       free_state (sd);
498       return 0;
499     }
500   if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
501     {
502       free_state (sd);
503       return 0;
504     }      
505
506   /* CPU specific initialization.  */
507   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
508     {
509       SIM_CPU *cpu = STATE_CPU (sd, i);
510
511       CPU_PC_FETCH (cpu) = m68hc11_pc_get;
512       CPU_PC_STORE (cpu) = m68hc11_pc_set;
513     }
514
515   return sd;
516 }
517
518
519 void
520 sim_close (SIM_DESC sd, int quitting)
521 {
522   /* shut down modules */
523   sim_module_uninstall (sd);
524
525   /* Ensure that any resources allocated through the callback
526      mechanism are released: */
527   sim_io_shutdown (sd);
528
529   /* FIXME - free SD */
530   sim_state_free (sd);
531   return;
532 }
533
534 /* Generic implementation of sim_engine_run that works within the
535    sim_engine setjmp/longjmp framework. */
536
537 void
538 sim_engine_run (SIM_DESC sd,
539                 int next_cpu_nr,        /* ignore */
540                 int nr_cpus,    /* ignore */
541                 int siggnal)    /* ignore */
542 {
543   sim_cpu *cpu;
544
545   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
546   cpu = STATE_CPU (sd, 0);
547   while (1)
548     {
549       cpu_single_step (cpu);
550
551       /* process any events */
552       if (sim_events_tickn (sd, cpu->cpu_current_cycle))
553         {
554           sim_events_process (sd);
555         }
556     }
557 }
558
559 void
560 sim_info (SIM_DESC sd, int verbose)
561 {
562   const char *cpu_type;
563   const struct bfd_arch_info *arch;
564
565   /* Nothing to do if there is no verbose flag set.  */
566   if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
567     return;
568
569   arch = STATE_ARCHITECTURE (sd);
570   if (arch->arch == bfd_arch_m68hc11)
571     cpu_type = "68HC11";
572   else
573     cpu_type = "68HC12";
574
575   sim_io_eprintf (sd, "Simulator info:\n");
576   sim_io_eprintf (sd, "  CPU Motorola %s\n", cpu_type);
577   sim_get_info (sd, 0);
578   sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
579 }
580
581 SIM_RC
582 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
583                      char **argv, char **env)
584 {
585   return sim_prepare_for_program (sd, abfd);
586 }
587
588 int
589 sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
590 {
591   sim_cpu *cpu;
592   uint16 val;
593   int size = 2;
594
595   cpu = STATE_CPU (sd, 0);
596   switch (rn)
597     {
598     case A_REGNUM:
599       val = cpu_get_a (cpu);
600       size = 1;
601       break;
602
603     case B_REGNUM:
604       val = cpu_get_b (cpu);
605       size = 1;
606       break;
607
608     case D_REGNUM:
609       val = cpu_get_d (cpu);
610       break;
611
612     case X_REGNUM:
613       val = cpu_get_x (cpu);
614       break;
615
616     case Y_REGNUM:
617       val = cpu_get_y (cpu);
618       break;
619
620     case SP_REGNUM:
621       val = cpu_get_sp (cpu);
622       break;
623
624     case PC_REGNUM:
625       val = cpu_get_pc (cpu);
626       break;
627
628     case PSW_REGNUM:
629       val = cpu_get_ccr (cpu);
630       size = 1;
631       break;
632
633     case PAGE_REGNUM:
634       val = cpu_get_page (cpu);
635       size = 1;
636       break;
637
638     default:
639       val = 0;
640       break;
641     }
642   if (size == 1)
643     {
644       memory[0] = val;
645     }
646   else
647     {
648       memory[0] = val >> 8;
649       memory[1] = val & 0x0FF;
650     }
651   return size;
652 }
653
654 int
655 sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
656 {
657   uint16 val;
658   sim_cpu *cpu;
659
660   cpu = STATE_CPU (sd, 0);
661
662   val = *memory++;
663   if (length == 2)
664     val = (val << 8) | *memory;
665
666   switch (rn)
667     {
668     case D_REGNUM:
669       cpu_set_d (cpu, val);
670       break;
671
672     case A_REGNUM:
673       cpu_set_a (cpu, val);
674       return 1;
675
676     case B_REGNUM:
677       cpu_set_b (cpu, val);
678       return 1;
679
680     case X_REGNUM:
681       cpu_set_x (cpu, val);
682       break;
683
684     case Y_REGNUM:
685       cpu_set_y (cpu, val);
686       break;
687
688     case SP_REGNUM:
689       cpu_set_sp (cpu, val);
690       break;
691
692     case PC_REGNUM:
693       cpu_set_pc (cpu, val);
694       break;
695
696     case PSW_REGNUM:
697       cpu_set_ccr (cpu, val);
698       return 1;
699
700     case PAGE_REGNUM:
701       cpu_set_page (cpu, val);
702       return 1;
703
704     default:
705       break;
706     }
707
708   return 2;
709 }
710
711 /* Halt the simulator after just one instruction */
712
713 static void
714 has_stepped (SIM_DESC sd,
715              void *data)
716 {
717   ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
718   sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
719 }
720
721
722 /* Generic resume - assumes the existance of sim_engine_run */
723
724 void
725 sim_resume (SIM_DESC sd,
726             int step,
727             int siggnal)
728 {
729   sim_engine *engine = STATE_ENGINE (sd);
730   jmp_buf buf;
731   int jmpval;
732
733   ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
734
735   /* we only want to be single stepping the simulator once */
736   if (engine->stepper != NULL)
737     {
738       sim_events_deschedule (sd, engine->stepper);
739       engine->stepper = NULL;
740     }
741   sim_module_resume (sd);
742
743   /* run/resume the simulator */
744   engine->jmpbuf = &buf;
745   jmpval = setjmp (buf);
746   if (jmpval == sim_engine_start_jmpval
747       || jmpval == sim_engine_restart_jmpval)
748     {
749       int last_cpu_nr = sim_engine_last_cpu_nr (sd);
750       int next_cpu_nr = sim_engine_next_cpu_nr (sd);
751       int nr_cpus = sim_engine_nr_cpus (sd);
752
753       sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
754       if (next_cpu_nr >= nr_cpus)
755         next_cpu_nr = 0;
756
757       /* Only deliver the siggnal ]sic] the first time through - don't
758          re-deliver any siggnal during a restart. */
759       if (jmpval == sim_engine_restart_jmpval)
760         siggnal = 0;
761
762       /* Install the stepping event after having processed some
763          pending events.  This is necessary for HC11/HC12 simulator
764          because the tick counter is incremented by the number of cycles
765          the instruction took.  Some pending ticks to process can still
766          be recorded internally by the simulator and sim_events_preprocess
767          will handle them.  If the stepping event is inserted before,
768          these pending ticks will raise the event and the simulator will
769          stop without having executed any instruction.  */
770       if (step)
771         engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
772
773 #ifdef SIM_CPU_EXCEPTION_RESUME
774       {
775         sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
776         SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
777       }
778 #endif
779
780       sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
781     }
782   engine->jmpbuf = NULL;
783
784   sim_module_suspend (sd);
785 }