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