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 2, or (at your option)
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 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. */
23 #include "sim-assert.h"
25 #include "sim-options.h"
27 #include "hw-device.h"
29 #include "elf32-m68hc1x.h"
32 # define MONITOR_BASE (0x0C000)
33 # define MONITOR_SIZE (0x04000)
36 static void sim_get_info (SIM_DESC sd, char *cmd);
39 char *interrupt_names[] = {
47 #if defined(__GNUC__) && defined(__OPTIMIZE__)
48 #define INLINE __inline__
60 struct sim_info_list dev_list_68hc11[] = {
62 {"timer", "/m68hc11/m68hc11tim"},
63 {"sio", "/m68hc11/m68hc11sio"},
64 {"spi", "/m68hc11/m68hc11spi"},
65 {"eeprom", "/m68hc11/m68hc11eepr"},
69 struct sim_info_list dev_list_68hc12[] = {
71 {"timer", "/m68hc12/m68hc12tim"},
72 {"sio", "/m68hc12/m68hc12sio"},
73 {"spi", "/m68hc12/m68hc12spi"},
74 {"eeprom", "/m68hc12/m68hc12eepr"},
78 /* Cover function of sim_state_free to free the cpu buffers as well. */
81 free_state (SIM_DESC sd)
83 if (STATE_MODULES (sd) != NULL)
84 sim_module_uninstall (sd);
89 /* Give some information about the simulator. */
91 sim_get_info (SIM_DESC sd, char *cmd)
95 cpu = STATE_CPU (sd, 0);
96 if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
100 struct sim_info_list *dev_list;
101 const struct bfd_arch_info *arch;
103 arch = STATE_ARCHITECTURE (sd);
106 if (arch->arch == bfd_arch_m68hc11)
107 dev_list = dev_list_68hc11;
109 dev_list = dev_list_68hc12;
111 for (i = 0; dev_list[i].name; i++)
112 if (strcmp (cmd, dev_list[i].name) == 0)
115 if (dev_list[i].name == 0)
117 sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
118 sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
121 hw_dev = sim_hw_parse (sd, dev_list[i].device);
124 sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
127 hw_ioctl (hw_dev, 23, 0);
132 interrupts_info (sd, &cpu->cpu_interrupts);
137 sim_board_reset (SIM_DESC sd)
141 const struct bfd_arch_info *arch;
142 const char *cpu_type;
144 cpu = STATE_CPU (sd, 0);
145 arch = STATE_ARCHITECTURE (sd);
147 /* hw_cpu = sim_hw_parse (sd, "/"); */
148 if (arch->arch == bfd_arch_m68hc11)
150 cpu->cpu_type = CPU_M6811;
151 cpu_type = "/m68hc11";
155 cpu->cpu_type = CPU_M6812;
156 cpu_type = "/m68hc12";
159 hw_cpu = sim_hw_parse (sd, cpu_type);
162 sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
167 hw_port_event (hw_cpu, 3, 0);
172 sim_hw_configure (SIM_DESC sd)
174 const struct bfd_arch_info *arch;
175 struct hw *device_tree;
178 arch = STATE_ARCHITECTURE (sd);
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)
187 cpu->cpu_interpretor = cpu_interp_m6811;
188 if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
190 /* Allocate core managed memory */
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",
198 sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
199 if (cpu->bank_start < cpu->bank_end)
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");
206 if (cpu->cpu_start_mode)
208 sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
210 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
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");
216 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
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");
224 /* Create the SPI device. */
225 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
227 sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
228 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
230 if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
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"); */
238 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
240 sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
241 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
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");
251 cpu->cpu_interpretor = cpu_interp_m6812;
252 if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
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",
259 if (cpu->bank_start < cpu->bank_end)
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");
265 sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
268 if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
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");
274 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
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");
282 /* Create the SPI device. */
283 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
285 sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
286 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
288 if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
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");
295 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
297 sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
298 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
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");
310 /* Get the memory bank parameters by looking at the global symbols
311 defined by the linker. */
313 sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
317 long symbol_count, i;
322 cpu = STATE_CPU (sd, 0);
324 symsize = bfd_get_symtab_upper_bound (abfd);
327 sim_io_eprintf (sd, "Cannot read symbols of program");
330 asymbols = (asymbol **) xmalloc (symsize);
331 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
332 if (symbol_count < 0)
334 sim_io_eprintf (sd, "Cannot read symbols of program");
339 for (i = 0, current = asymbols; i < symbol_count; i++, current++)
341 const char* name = bfd_asymbol_name (*current);
343 if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
345 cpu->bank_start = bfd_asymbol_value (*current);
347 else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
349 size = bfd_asymbol_value (*current);
351 else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
353 cpu->bank_virtual = bfd_asymbol_value (*current);
358 cpu->bank_end = cpu->bank_start + size;
360 for (; size > 1; size >>= 1)
367 sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
372 cpu = STATE_CPU (sd, 0);
378 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
379 elf_flags = elf_elfheader (abfd)->e_flags;
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)
386 if (s->flags & SEC_LOAD)
390 size = bfd_get_section_size (s);
395 if (STATE_LOAD_AT_LMA_P (sd))
396 lma = bfd_section_lma (abfd, s);
398 lma = bfd_section_vma (abfd, s);
400 if (lma <= 0xFFFE && lma+size >= 0x10000)
401 cpu->cpu_use_elf_start = 0;
406 if (elf_flags & E_M68HC12_BANKS)
408 if (sim_get_bank_parameters (sd, abfd) != 0)
409 sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
413 if (!sim_hw_configure (sd))
416 /* reset all state information */
417 sim_board_reset (sd);
423 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
424 bfd *abfd, char **argv)
429 sd = sim_state_alloc (kind, callback);
430 cpu = STATE_CPU (sd, 0);
432 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
434 /* for compatibility */
435 current_alignment = NONSTRICT_ALIGNMENT;
436 current_target_byte_order = BIG_ENDIAN;
438 cpu_initialize (sd, cpu);
440 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
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
449 if (sim_parse_args (sd, argv) != SIM_RC_OK)
451 /* Uninstall the modules to avoid memory leaks,
452 file descriptor leaks, etc. */
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)
467 /* Establish any remaining configuration options. */
468 if (sim_config (sd) != SIM_RC_OK)
474 if (sim_post_argv_init (sd) != SIM_RC_OK)
476 /* Uninstall the modules to avoid memory leaks,
477 file descriptor leaks, etc. */
481 if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
487 /* Fudge our descriptor. */
493 sim_close (SIM_DESC sd, int quitting)
495 /* shut down modules */
496 sim_module_uninstall (sd);
498 /* Ensure that any resources allocated through the callback
499 mechanism are released: */
500 sim_io_shutdown (sd);
502 /* FIXME - free SD */
508 sim_set_profile (int n)
513 sim_set_profile_size (int n)
517 /* Generic implementation of sim_engine_run that works within the
518 sim_engine setjmp/longjmp framework. */
521 sim_engine_run (SIM_DESC sd,
522 int next_cpu_nr, /* ignore */
523 int nr_cpus, /* ignore */
524 int siggnal) /* ignore */
528 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
529 cpu = STATE_CPU (sd, 0);
532 cpu_single_step (cpu);
534 /* process any events */
535 if (sim_events_tickn (sd, cpu->cpu_current_cycle))
537 sim_events_process (sd);
543 sim_trace (SIM_DESC sd)
545 sim_resume (sd, 0, 0);
550 sim_info (SIM_DESC sd, int verbose)
552 const char *cpu_type;
553 const struct bfd_arch_info *arch;
555 /* Nothing to do if there is no verbose flag set. */
556 if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
559 arch = STATE_ARCHITECTURE (sd);
560 if (arch->arch == bfd_arch_m68hc11)
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));
572 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
573 char **argv, char **env)
575 return sim_prepare_for_program (sd, abfd);
580 sim_set_callbacks (host_callback *p)
582 /* m6811_callback = p; */
587 sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
593 cpu = STATE_CPU (sd, 0);
597 val = cpu_get_a (cpu);
602 val = cpu_get_b (cpu);
607 val = cpu_get_d (cpu);
611 val = cpu_get_x (cpu);
615 val = cpu_get_y (cpu);
619 val = cpu_get_sp (cpu);
623 val = cpu_get_pc (cpu);
627 val = cpu_get_ccr (cpu);
632 val = cpu_get_page (cpu);
646 memory[0] = val >> 8;
647 memory[1] = val & 0x0FF;
653 sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
658 cpu = STATE_CPU (sd, 0);
662 val = (val << 8) | *memory;
667 cpu_set_d (cpu, val);
671 cpu_set_a (cpu, val);
675 cpu_set_b (cpu, val);
679 cpu_set_x (cpu, val);
683 cpu_set_y (cpu, val);
687 cpu_set_sp (cpu, val);
691 cpu_set_pc (cpu, val);
695 cpu_set_ccr (cpu, val);
699 cpu_set_page (cpu, val);
716 sim_do_command (SIM_DESC sd, char *cmd)
718 char *mm_cmd = "memory-map";
719 char *int_cmd = "interrupt";
722 cpu = STATE_CPU (sd, 0);
723 /* Commands available from GDB: */
724 if (sim_args_command (sd, cmd) != SIM_RC_OK)
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))
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");
734 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
737 /* If the architecture changed, re-configure. */
738 if (STATE_ARCHITECTURE (sd) != cpu->cpu_configured_arch)
739 sim_hw_configure (sd);
742 /* Halt the simulator after just one instruction */
745 has_stepped (SIM_DESC sd,
748 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
749 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
753 /* Generic resume - assumes the existance of sim_engine_run */
756 sim_resume (SIM_DESC sd,
760 sim_engine *engine = STATE_ENGINE (sd);
764 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
766 /* we only want to be single stepping the simulator once */
767 if (engine->stepper != NULL)
769 sim_events_deschedule (sd, engine->stepper);
770 engine->stepper = NULL;
772 sim_module_resume (sd);
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)
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);
784 sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
785 if (next_cpu_nr >= nr_cpus)
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)
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. */
802 engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
804 #ifdef SIM_CPU_EXCEPTION_RESUME
806 sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
807 SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
811 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
813 engine->jmpbuf = NULL;
815 sim_module_suspend (sd);