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)
6 This file is part of GDB, the GNU debugger.
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.
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.
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/>. */
22 #include "sim-assert.h"
24 #include "sim-options.h"
26 #include "hw-device.h"
28 #include "elf32-m68hc1x.h"
31 # define MONITOR_BASE (0x0C000)
32 # define MONITOR_SIZE (0x04000)
35 static void sim_get_info (SIM_DESC sd, char *cmd);
38 char *interrupt_names[] = {
46 #if defined(__GNUC__) && defined(__OPTIMIZE__)
47 #define INLINE __inline__
59 struct sim_info_list dev_list_68hc11[] = {
61 {"timer", "/m68hc11/m68hc11tim"},
62 {"sio", "/m68hc11/m68hc11sio"},
63 {"spi", "/m68hc11/m68hc11spi"},
64 {"eeprom", "/m68hc11/m68hc11eepr"},
68 struct sim_info_list dev_list_68hc12[] = {
70 {"timer", "/m68hc12/m68hc12tim"},
71 {"sio", "/m68hc12/m68hc12sio"},
72 {"spi", "/m68hc12/m68hc12spi"},
73 {"eeprom", "/m68hc12/m68hc12eepr"},
77 /* Cover function of sim_state_free to free the cpu buffers as well. */
80 free_state (SIM_DESC sd)
82 if (STATE_MODULES (sd) != NULL)
83 sim_module_uninstall (sd);
88 /* Give some information about the simulator. */
90 sim_get_info (SIM_DESC sd, char *cmd)
94 cpu = STATE_CPU (sd, 0);
95 if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
99 struct sim_info_list *dev_list;
100 const struct bfd_arch_info *arch;
102 arch = STATE_ARCHITECTURE (sd);
105 if (arch->arch == bfd_arch_m68hc11)
106 dev_list = dev_list_68hc11;
108 dev_list = dev_list_68hc12;
110 for (i = 0; dev_list[i].name; i++)
111 if (strcmp (cmd, dev_list[i].name) == 0)
114 if (dev_list[i].name == 0)
116 sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
117 sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
120 hw_dev = sim_hw_parse (sd, dev_list[i].device);
123 sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
126 hw_ioctl (hw_dev, 23, 0);
131 interrupts_info (sd, &cpu->cpu_interrupts);
136 sim_board_reset (SIM_DESC sd)
140 const struct bfd_arch_info *arch;
141 const char *cpu_type;
143 cpu = STATE_CPU (sd, 0);
144 arch = STATE_ARCHITECTURE (sd);
146 /* hw_cpu = sim_hw_parse (sd, "/"); */
147 if (arch->arch == bfd_arch_m68hc11)
149 cpu->cpu_type = CPU_M6811;
150 cpu_type = "/m68hc11";
154 cpu->cpu_type = CPU_M6812;
155 cpu_type = "/m68hc12";
158 hw_cpu = sim_hw_parse (sd, cpu_type);
161 sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
166 hw_port_event (hw_cpu, 3, 0);
171 sim_hw_configure (SIM_DESC sd)
173 const struct bfd_arch_info *arch;
174 struct hw *device_tree;
177 arch = STATE_ARCHITECTURE (sd);
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)
186 cpu->cpu_interpretor = cpu_interp_m6811;
187 if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
189 /* Allocate core managed memory */
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",
197 sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
198 if (cpu->bank_start < cpu->bank_end)
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");
205 if (cpu->cpu_start_mode)
207 sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
209 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
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");
215 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
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");
223 /* Create the SPI device. */
224 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
226 sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
227 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
229 if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
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"); */
237 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
239 sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
240 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
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");
250 cpu->cpu_interpretor = cpu_interp_m6812;
251 if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
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",
258 if (cpu->bank_start < cpu->bank_end)
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");
264 sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
267 if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
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");
273 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
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");
281 /* Create the SPI device. */
282 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
284 sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
285 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
287 if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
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");
294 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
296 sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
297 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
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");
309 /* Get the memory bank parameters by looking at the global symbols
310 defined by the linker. */
312 sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
316 long symbol_count, i;
321 cpu = STATE_CPU (sd, 0);
323 symsize = bfd_get_symtab_upper_bound (abfd);
326 sim_io_eprintf (sd, "Cannot read symbols of program");
329 asymbols = (asymbol **) xmalloc (symsize);
330 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
331 if (symbol_count < 0)
333 sim_io_eprintf (sd, "Cannot read symbols of program");
338 for (i = 0, current = asymbols; i < symbol_count; i++, current++)
340 const char* name = bfd_asymbol_name (*current);
342 if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
344 cpu->bank_start = bfd_asymbol_value (*current);
346 else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
348 size = bfd_asymbol_value (*current);
350 else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
352 cpu->bank_virtual = bfd_asymbol_value (*current);
357 cpu->bank_end = cpu->bank_start + size;
359 for (; size > 1; size >>= 1)
366 sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
371 cpu = STATE_CPU (sd, 0);
377 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
378 elf_flags = elf_elfheader (abfd)->e_flags;
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)
385 if (s->flags & SEC_LOAD)
389 size = bfd_get_section_size (s);
394 if (STATE_LOAD_AT_LMA_P (sd))
395 lma = bfd_section_lma (abfd, s);
397 lma = bfd_section_vma (abfd, s);
399 if (lma <= 0xFFFE && lma+size >= 0x10000)
400 cpu->cpu_use_elf_start = 0;
405 if (elf_flags & E_M68HC12_BANKS)
407 if (sim_get_bank_parameters (sd, abfd) != 0)
408 sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
412 if (!sim_hw_configure (sd))
415 /* reset all state information */
416 sim_board_reset (sd);
422 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
423 bfd *abfd, char **argv)
428 sd = sim_state_alloc (kind, callback);
429 cpu = STATE_CPU (sd, 0);
431 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
433 /* for compatibility */
434 current_alignment = NONSTRICT_ALIGNMENT;
435 current_target_byte_order = BIG_ENDIAN;
437 cpu_initialize (sd, cpu);
439 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
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
448 if (sim_parse_args (sd, argv) != SIM_RC_OK)
450 /* Uninstall the modules to avoid memory leaks,
451 file descriptor leaks, etc. */
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)
466 /* Establish any remaining configuration options. */
467 if (sim_config (sd) != SIM_RC_OK)
473 if (sim_post_argv_init (sd) != SIM_RC_OK)
475 /* Uninstall the modules to avoid memory leaks,
476 file descriptor leaks, etc. */
480 if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
486 /* Fudge our descriptor. */
492 sim_close (SIM_DESC sd, int quitting)
494 /* shut down modules */
495 sim_module_uninstall (sd);
497 /* Ensure that any resources allocated through the callback
498 mechanism are released: */
499 sim_io_shutdown (sd);
501 /* FIXME - free SD */
507 sim_set_profile (int n)
512 sim_set_profile_size (int n)
516 /* Generic implementation of sim_engine_run that works within the
517 sim_engine setjmp/longjmp framework. */
520 sim_engine_run (SIM_DESC sd,
521 int next_cpu_nr, /* ignore */
522 int nr_cpus, /* ignore */
523 int siggnal) /* ignore */
527 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
528 cpu = STATE_CPU (sd, 0);
531 cpu_single_step (cpu);
533 /* process any events */
534 if (sim_events_tickn (sd, cpu->cpu_current_cycle))
536 sim_events_process (sd);
542 sim_trace (SIM_DESC sd)
544 sim_resume (sd, 0, 0);
549 sim_info (SIM_DESC sd, int verbose)
551 const char *cpu_type;
552 const struct bfd_arch_info *arch;
554 /* Nothing to do if there is no verbose flag set. */
555 if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
558 arch = STATE_ARCHITECTURE (sd);
559 if (arch->arch == bfd_arch_m68hc11)
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));
571 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
572 char **argv, char **env)
574 return sim_prepare_for_program (sd, abfd);
579 sim_set_callbacks (host_callback *p)
581 /* m6811_callback = p; */
586 sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
592 cpu = STATE_CPU (sd, 0);
596 val = cpu_get_a (cpu);
601 val = cpu_get_b (cpu);
606 val = cpu_get_d (cpu);
610 val = cpu_get_x (cpu);
614 val = cpu_get_y (cpu);
618 val = cpu_get_sp (cpu);
622 val = cpu_get_pc (cpu);
626 val = cpu_get_ccr (cpu);
631 val = cpu_get_page (cpu);
645 memory[0] = val >> 8;
646 memory[1] = val & 0x0FF;
652 sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
657 cpu = STATE_CPU (sd, 0);
661 val = (val << 8) | *memory;
666 cpu_set_d (cpu, val);
670 cpu_set_a (cpu, val);
674 cpu_set_b (cpu, val);
678 cpu_set_x (cpu, val);
682 cpu_set_y (cpu, val);
686 cpu_set_sp (cpu, val);
690 cpu_set_pc (cpu, val);
694 cpu_set_ccr (cpu, val);
698 cpu_set_page (cpu, val);
715 sim_do_command (SIM_DESC sd, char *cmd)
717 char *mm_cmd = "memory-map";
718 char *int_cmd = "interrupt";
721 cpu = STATE_CPU (sd, 0);
722 /* Commands available from GDB: */
723 if (sim_args_command (sd, cmd) != SIM_RC_OK)
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))
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");
733 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
736 /* If the architecture changed, re-configure. */
737 if (STATE_ARCHITECTURE (sd) != cpu->cpu_configured_arch)
738 sim_hw_configure (sd);
741 /* Halt the simulator after just one instruction */
744 has_stepped (SIM_DESC sd,
747 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
748 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
752 /* Generic resume - assumes the existance of sim_engine_run */
755 sim_resume (SIM_DESC sd,
759 sim_engine *engine = STATE_ENGINE (sd);
763 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
765 /* we only want to be single stepping the simulator once */
766 if (engine->stepper != NULL)
768 sim_events_deschedule (sd, engine->stepper);
769 engine->stepper = NULL;
771 sim_module_resume (sd);
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)
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);
783 sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
784 if (next_cpu_nr >= nr_cpus)
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)
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. */
801 engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
803 #ifdef SIM_CPU_EXCEPTION_RESUME
805 sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
806 SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
810 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
812 engine->jmpbuf = NULL;
814 sim_module_suspend (sd);