1 /* interp.c -- Simulator for Motorola 68HC11/68HC12
2 Copyright (C) 1999-2015 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
5 This file is part of GDB, the GNU debugger.
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.
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.
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/>. */
21 #include "sim-assert.h"
23 #include "sim-options.h"
25 #include "hw-device.h"
27 #include "elf32-m68hc1x.h"
30 # define MONITOR_BASE (0x0C000)
31 # define MONITOR_SIZE (0x04000)
34 static void sim_get_info (SIM_DESC sd
, char *cmd
);
37 char *interrupt_names
[] = {
45 #if defined(__GNUC__) && defined(__OPTIMIZE__)
46 #define INLINE __inline__
58 struct sim_info_list dev_list_68hc11
[] = {
60 {"timer", "/m68hc11/m68hc11tim"},
61 {"sio", "/m68hc11/m68hc11sio"},
62 {"spi", "/m68hc11/m68hc11spi"},
63 {"eeprom", "/m68hc11/m68hc11eepr"},
67 struct sim_info_list dev_list_68hc12
[] = {
69 {"timer", "/m68hc12/m68hc12tim"},
70 {"sio", "/m68hc12/m68hc12sio"},
71 {"spi", "/m68hc12/m68hc12spi"},
72 {"eeprom", "/m68hc12/m68hc12eepr"},
76 /* Cover function of sim_state_free to free the cpu buffers as well. */
79 free_state (SIM_DESC sd
)
81 if (STATE_MODULES (sd
) != NULL
)
82 sim_module_uninstall (sd
);
87 /* Give some information about the simulator. */
89 sim_get_info (SIM_DESC sd
, char *cmd
)
93 cpu
= STATE_CPU (sd
, 0);
94 if (cmd
!= 0 && (cmd
[0] == ' ' || cmd
[0] == '-'))
98 struct sim_info_list
*dev_list
;
99 const struct bfd_arch_info
*arch
;
101 arch
= STATE_ARCHITECTURE (sd
);
104 if (arch
->arch
== bfd_arch_m68hc11
)
105 dev_list
= dev_list_68hc11
;
107 dev_list
= dev_list_68hc12
;
109 for (i
= 0; dev_list
[i
].name
; i
++)
110 if (strcmp (cmd
, dev_list
[i
].name
) == 0)
113 if (dev_list
[i
].name
== 0)
115 sim_io_eprintf (sd
, "Device '%s' not found.\n", cmd
);
116 sim_io_eprintf (sd
, "Valid devices: cpu timer sio eeprom\n");
119 hw_dev
= sim_hw_parse (sd
, dev_list
[i
].device
);
122 sim_io_eprintf (sd
, "Device '%s' not found\n", dev_list
[i
].device
);
125 hw_ioctl (hw_dev
, 23, 0);
130 interrupts_info (sd
, &cpu
->cpu_interrupts
);
135 sim_board_reset (SIM_DESC sd
)
139 const struct bfd_arch_info
*arch
;
140 const char *cpu_type
;
142 cpu
= STATE_CPU (sd
, 0);
143 arch
= STATE_ARCHITECTURE (sd
);
145 /* hw_cpu = sim_hw_parse (sd, "/"); */
146 if (arch
->arch
== bfd_arch_m68hc11
)
148 cpu
->cpu_type
= CPU_M6811
;
149 cpu_type
= "/m68hc11";
153 cpu
->cpu_type
= CPU_M6812
;
154 cpu_type
= "/m68hc12";
157 hw_cpu
= sim_hw_parse (sd
, cpu_type
);
160 sim_io_eprintf (sd
, "%s cpu not found in device tree.", cpu_type
);
165 hw_port_event (hw_cpu
, 3, 0);
170 sim_hw_configure (SIM_DESC sd
)
172 const struct bfd_arch_info
*arch
;
173 struct hw
*device_tree
;
176 arch
= STATE_ARCHITECTURE (sd
);
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
)
185 cpu
->cpu_interpretor
= cpu_interp_m6811
;
186 if (hw_tree_find_property (device_tree
, "/m68hc11/reg") == 0)
188 /* Allocate core managed memory */
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",
196 sim_hw_parse (sd
, "/m68hc11/reg 0x1000 0x03F");
197 if (cpu
->bank_start
< cpu
->bank_end
)
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");
204 if (cpu
->cpu_start_mode
)
206 sim_hw_parse (sd
, "/m68hc11/mode %s", cpu
->cpu_start_mode
);
208 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11sio/reg") == 0)
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");
214 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11tim/reg") == 0)
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");
222 /* Create the SPI device. */
223 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11spi/reg") == 0)
225 sim_hw_parse (sd
, "/m68hc11/m68hc11spi/reg 0x28 0x3");
226 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
228 if (hw_tree_find_property (device_tree
, "/m68hc11/nvram/reg") == 0)
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"); */
236 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11eepr/reg") == 0)
238 sim_hw_parse (sd
, "/m68hc11/m68hc11eepr/reg 0xb000 512");
239 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
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");
249 cpu
->cpu_interpretor
= cpu_interp_m6812
;
250 if (hw_tree_find_property (device_tree
, "/m68hc12/reg") == 0)
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",
257 if (cpu
->bank_start
< cpu
->bank_end
)
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");
263 sim_hw_parse (sd
, "/m68hc12/reg 0x0 0x3FF");
266 if (!hw_tree_find_property (device_tree
, "/m68hc12/m68hc12sio@1/reg"))
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");
272 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12tim/reg") == 0)
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");
280 /* Create the SPI device. */
281 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12spi/reg") == 0)
283 sim_hw_parse (sd
, "/m68hc12/m68hc12spi/reg 0x28 0x3");
284 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
286 if (hw_tree_find_property (device_tree
, "/m68hc12/nvram/reg") == 0)
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");
293 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12eepr/reg") == 0)
295 sim_hw_parse (sd
, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
296 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
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");
308 /* Get the memory bank parameters by looking at the global symbols
309 defined by the linker. */
311 sim_get_bank_parameters (SIM_DESC sd
, bfd
* abfd
)
315 long symbol_count
, i
;
320 cpu
= STATE_CPU (sd
, 0);
322 symsize
= bfd_get_symtab_upper_bound (abfd
);
325 sim_io_eprintf (sd
, "Cannot read symbols of program");
328 asymbols
= (asymbol
**) xmalloc (symsize
);
329 symbol_count
= bfd_canonicalize_symtab (abfd
, asymbols
);
330 if (symbol_count
< 0)
332 sim_io_eprintf (sd
, "Cannot read symbols of program");
337 for (i
= 0, current
= asymbols
; i
< symbol_count
; i
++, current
++)
339 const char* name
= bfd_asymbol_name (*current
);
341 if (strcmp (name
, BFD_M68HC11_BANK_START_NAME
) == 0)
343 cpu
->bank_start
= bfd_asymbol_value (*current
);
345 else if (strcmp (name
, BFD_M68HC11_BANK_SIZE_NAME
) == 0)
347 size
= bfd_asymbol_value (*current
);
349 else if (strcmp (name
, BFD_M68HC11_BANK_VIRTUAL_NAME
) == 0)
351 cpu
->bank_virtual
= bfd_asymbol_value (*current
);
356 cpu
->bank_end
= cpu
->bank_start
+ size
;
358 for (; size
> 1; size
>>= 1)
365 sim_prepare_for_program (SIM_DESC sd
, bfd
* abfd
)
370 cpu
= STATE_CPU (sd
, 0);
376 if (bfd_get_flavour (abfd
) == bfd_target_elf_flavour
)
377 elf_flags
= elf_elfheader (abfd
)->e_flags
;
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
)
384 if (s
->flags
& SEC_LOAD
)
388 size
= bfd_get_section_size (s
);
393 if (STATE_LOAD_AT_LMA_P (sd
))
394 lma
= bfd_section_lma (abfd
, s
);
396 lma
= bfd_section_vma (abfd
, s
);
398 if (lma
<= 0xFFFE && lma
+size
>= 0x10000)
399 cpu
->cpu_use_elf_start
= 0;
404 if (elf_flags
& E_M68HC12_BANKS
)
406 if (sim_get_bank_parameters (sd
, abfd
) != 0)
407 sim_io_eprintf (sd
, "Memory bank parameters are not initialized\n");
411 if (!sim_hw_configure (sd
))
414 /* reset all state information */
415 sim_board_reset (sd
);
421 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
422 bfd
*abfd
, char **argv
)
427 sd
= sim_state_alloc (kind
, callback
);
428 cpu
= STATE_CPU (sd
, 0);
430 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
432 /* for compatibility */
433 current_alignment
= NONSTRICT_ALIGNMENT
;
434 current_target_byte_order
= BIG_ENDIAN
;
436 cpu_initialize (sd
, cpu
);
438 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
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
447 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
449 /* Uninstall the modules to avoid memory leaks,
450 file descriptor leaks, etc. */
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
)
465 /* Establish any remaining configuration options. */
466 if (sim_config (sd
) != SIM_RC_OK
)
472 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
474 /* Uninstall the modules to avoid memory leaks,
475 file descriptor leaks, etc. */
479 if (sim_prepare_for_program (sd
, abfd
) != SIM_RC_OK
)
485 /* Fudge our descriptor. */
491 sim_close (SIM_DESC sd
, int quitting
)
493 /* shut down modules */
494 sim_module_uninstall (sd
);
496 /* Ensure that any resources allocated through the callback
497 mechanism are released: */
498 sim_io_shutdown (sd
);
500 /* FIXME - free SD */
505 /* Generic implementation of sim_engine_run that works within the
506 sim_engine setjmp/longjmp framework. */
509 sim_engine_run (SIM_DESC sd
,
510 int next_cpu_nr
, /* ignore */
511 int nr_cpus
, /* ignore */
512 int siggnal
) /* ignore */
516 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
517 cpu
= STATE_CPU (sd
, 0);
520 cpu_single_step (cpu
);
522 /* process any events */
523 if (sim_events_tickn (sd
, cpu
->cpu_current_cycle
))
525 sim_events_process (sd
);
531 sim_info (SIM_DESC sd
, int verbose
)
533 const char *cpu_type
;
534 const struct bfd_arch_info
*arch
;
536 /* Nothing to do if there is no verbose flag set. */
537 if (verbose
== 0 && STATE_VERBOSE_P (sd
) == 0)
540 arch
= STATE_ARCHITECTURE (sd
);
541 if (arch
->arch
== bfd_arch_m68hc11
)
546 sim_io_eprintf (sd
, "Simulator info:\n");
547 sim_io_eprintf (sd
, " CPU Motorola %s\n", cpu_type
);
548 sim_get_info (sd
, 0);
549 sim_module_info (sd
, verbose
|| STATE_VERBOSE_P (sd
));
553 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
554 char **argv
, char **env
)
556 return sim_prepare_for_program (sd
, abfd
);
560 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
566 cpu
= STATE_CPU (sd
, 0);
570 val
= cpu_get_a (cpu
);
575 val
= cpu_get_b (cpu
);
580 val
= cpu_get_d (cpu
);
584 val
= cpu_get_x (cpu
);
588 val
= cpu_get_y (cpu
);
592 val
= cpu_get_sp (cpu
);
596 val
= cpu_get_pc (cpu
);
600 val
= cpu_get_ccr (cpu
);
605 val
= cpu_get_page (cpu
);
619 memory
[0] = val
>> 8;
620 memory
[1] = val
& 0x0FF;
626 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
631 cpu
= STATE_CPU (sd
, 0);
635 val
= (val
<< 8) | *memory
;
640 cpu_set_d (cpu
, val
);
644 cpu_set_a (cpu
, val
);
648 cpu_set_b (cpu
, val
);
652 cpu_set_x (cpu
, val
);
656 cpu_set_y (cpu
, val
);
660 cpu_set_sp (cpu
, val
);
664 cpu_set_pc (cpu
, val
);
668 cpu_set_ccr (cpu
, val
);
672 cpu_set_page (cpu
, val
);
682 /* Halt the simulator after just one instruction */
685 has_stepped (SIM_DESC sd
,
688 ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
689 sim_engine_halt (sd
, NULL
, NULL
, NULL_CIA
, sim_stopped
, SIM_SIGTRAP
);
693 /* Generic resume - assumes the existance of sim_engine_run */
696 sim_resume (SIM_DESC sd
,
700 sim_engine
*engine
= STATE_ENGINE (sd
);
704 ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
706 /* we only want to be single stepping the simulator once */
707 if (engine
->stepper
!= NULL
)
709 sim_events_deschedule (sd
, engine
->stepper
);
710 engine
->stepper
= NULL
;
712 sim_module_resume (sd
);
714 /* run/resume the simulator */
715 engine
->jmpbuf
= &buf
;
716 jmpval
= setjmp (buf
);
717 if (jmpval
== sim_engine_start_jmpval
718 || jmpval
== sim_engine_restart_jmpval
)
720 int last_cpu_nr
= sim_engine_last_cpu_nr (sd
);
721 int next_cpu_nr
= sim_engine_next_cpu_nr (sd
);
722 int nr_cpus
= sim_engine_nr_cpus (sd
);
724 sim_events_preprocess (sd
, last_cpu_nr
>= nr_cpus
, next_cpu_nr
>= nr_cpus
);
725 if (next_cpu_nr
>= nr_cpus
)
728 /* Only deliver the siggnal ]sic] the first time through - don't
729 re-deliver any siggnal during a restart. */
730 if (jmpval
== sim_engine_restart_jmpval
)
733 /* Install the stepping event after having processed some
734 pending events. This is necessary for HC11/HC12 simulator
735 because the tick counter is incremented by the number of cycles
736 the instruction took. Some pending ticks to process can still
737 be recorded internally by the simulator and sim_events_preprocess
738 will handle them. If the stepping event is inserted before,
739 these pending ticks will raise the event and the simulator will
740 stop without having executed any instruction. */
742 engine
->stepper
= sim_events_schedule (sd
, 0, has_stepped
, sd
);
744 #ifdef SIM_CPU_EXCEPTION_RESUME
746 sim_cpu
* cpu
= STATE_CPU (sd
, next_cpu_nr
);
747 SIM_CPU_EXCEPTION_RESUME(sd
, cpu
, siggnal
);
751 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
);
753 engine
->jmpbuf
= NULL
;
755 sim_module_suspend (sd
);