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