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