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
6This file is part of GDB, the GNU debugger.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along 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
35static void sim_get_info (SIM_DESC sd, char *cmd);
36
37
38char *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
53struct sim_info_list
54{
55  const char *name;
56  const char *device;
57};
58
59struct 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
68struct 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
79static void
80free_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.  */
89static void
90sim_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
135void
136sim_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
170static int
171sim_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.  */
311static int
312sim_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
365static int
366sim_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
421SIM_DESC
422sim_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
491void
492sim_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
506void
507sim_set_profile (int n)
508{
509}
510
511void
512sim_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
519void
520sim_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
541int
542sim_trace (SIM_DESC sd)
543{
544  sim_resume (sd, 0, 0);
545  return 1;
546}
547
548void
549sim_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
570SIM_RC
571sim_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
578void
579sim_set_callbacks (host_callback *p)
580{
581  /*  m6811_callback = p; */
582}
583
584
585int
586sim_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
651int
652sim_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
708void
709sim_size (int s)
710{
711  ;
712}
713
714void
715sim_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
743static void
744has_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
754void
755sim_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}
816