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
);
42 struct sim_info_list dev_list_68hc11
[] = {
44 {"timer", "/m68hc11/m68hc11tim"},
45 {"sio", "/m68hc11/m68hc11sio"},
46 {"spi", "/m68hc11/m68hc11spi"},
47 {"eeprom", "/m68hc11/m68hc11eepr"},
51 struct sim_info_list dev_list_68hc12
[] = {
53 {"timer", "/m68hc12/m68hc12tim"},
54 {"sio", "/m68hc12/m68hc12sio"},
55 {"spi", "/m68hc12/m68hc12spi"},
56 {"eeprom", "/m68hc12/m68hc12eepr"},
60 /* Cover function of sim_state_free to free the cpu buffers as well. */
63 free_state (SIM_DESC sd
)
65 if (STATE_MODULES (sd
) != NULL
)
66 sim_module_uninstall (sd
);
71 /* Give some information about the simulator. */
73 sim_get_info (SIM_DESC sd
, char *cmd
)
77 cpu
= STATE_CPU (sd
, 0);
78 if (cmd
!= 0 && (cmd
[0] == ' ' || cmd
[0] == '-'))
82 struct sim_info_list
*dev_list
;
83 const struct bfd_arch_info
*arch
;
85 arch
= STATE_ARCHITECTURE (sd
);
88 if (arch
->arch
== bfd_arch_m68hc11
)
89 dev_list
= dev_list_68hc11
;
91 dev_list
= dev_list_68hc12
;
93 for (i
= 0; dev_list
[i
].name
; i
++)
94 if (strcmp (cmd
, dev_list
[i
].name
) == 0)
97 if (dev_list
[i
].name
== 0)
99 sim_io_eprintf (sd
, "Device '%s' not found.\n", cmd
);
100 sim_io_eprintf (sd
, "Valid devices: cpu timer sio eeprom\n");
103 hw_dev
= sim_hw_parse (sd
, dev_list
[i
].device
);
106 sim_io_eprintf (sd
, "Device '%s' not found\n", dev_list
[i
].device
);
109 hw_ioctl (hw_dev
, 23, 0);
114 interrupts_info (sd
, &cpu
->cpu_interrupts
);
119 sim_board_reset (SIM_DESC sd
)
123 const struct bfd_arch_info
*arch
;
124 const char *cpu_type
;
126 cpu
= STATE_CPU (sd
, 0);
127 arch
= STATE_ARCHITECTURE (sd
);
129 /* hw_cpu = sim_hw_parse (sd, "/"); */
130 if (arch
->arch
== bfd_arch_m68hc11
)
132 cpu
->cpu_type
= CPU_M6811
;
133 cpu_type
= "/m68hc11";
137 cpu
->cpu_type
= CPU_M6812
;
138 cpu_type
= "/m68hc12";
141 hw_cpu
= sim_hw_parse (sd
, cpu_type
);
144 sim_io_eprintf (sd
, "%s cpu not found in device tree.", cpu_type
);
149 hw_port_event (hw_cpu
, 3, 0);
154 sim_hw_configure (SIM_DESC sd
)
156 const struct bfd_arch_info
*arch
;
157 struct hw
*device_tree
;
160 arch
= STATE_ARCHITECTURE (sd
);
164 cpu
= STATE_CPU (sd
, 0);
165 cpu
->cpu_configured_arch
= arch
;
166 device_tree
= sim_hw_parse (sd
, "/");
167 if (arch
->arch
== bfd_arch_m68hc11
)
169 cpu
->cpu_interpretor
= cpu_interp_m6811
;
170 if (hw_tree_find_property (device_tree
, "/m68hc11/reg") == 0)
172 /* Allocate core managed memory */
175 sim_do_commandf (sd
, "memory region 0x%lx@%d,0x%lx",
176 /* MONITOR_BASE, MONITOR_SIZE */
177 0x8000, M6811_RAM_LEVEL
, 0x8000);
178 sim_do_commandf (sd
, "memory region 0x000@%d,0x8000",
180 sim_hw_parse (sd
, "/m68hc11/reg 0x1000 0x03F");
181 if (cpu
->bank_start
< cpu
->bank_end
)
183 sim_do_commandf (sd
, "memory region 0x%lx@%d,0x100000",
184 cpu
->bank_virtual
, M6811_RAM_LEVEL
);
185 sim_hw_parse (sd
, "/m68hc11/use_bank 1");
188 if (cpu
->cpu_start_mode
)
190 sim_hw_parse (sd
, "/m68hc11/mode %s", cpu
->cpu_start_mode
);
192 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11sio/reg") == 0)
194 sim_hw_parse (sd
, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
195 sim_hw_parse (sd
, "/m68hc11/m68hc11sio/backend stdio");
196 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
198 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11tim/reg") == 0)
200 /* M68hc11 Timer configuration. */
201 sim_hw_parse (sd
, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
202 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
203 sim_hw_parse (sd
, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
206 /* Create the SPI device. */
207 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11spi/reg") == 0)
209 sim_hw_parse (sd
, "/m68hc11/m68hc11spi/reg 0x28 0x3");
210 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
212 if (hw_tree_find_property (device_tree
, "/m68hc11/nvram/reg") == 0)
214 /* M68hc11 persistent ram configuration. */
215 sim_hw_parse (sd
, "/m68hc11/nvram/reg 0x0 256");
216 sim_hw_parse (sd
, "/m68hc11/nvram/file m68hc11.ram");
217 sim_hw_parse (sd
, "/m68hc11/nvram/mode save-modified");
218 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
220 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11eepr/reg") == 0)
222 sim_hw_parse (sd
, "/m68hc11/m68hc11eepr/reg 0xb000 512");
223 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
225 sim_hw_parse (sd
, "/m68hc11 > port-a cpu-write-port /m68hc11");
226 sim_hw_parse (sd
, "/m68hc11 > port-b cpu-write-port /m68hc11");
227 sim_hw_parse (sd
, "/m68hc11 > port-c cpu-write-port /m68hc11");
228 sim_hw_parse (sd
, "/m68hc11 > port-d cpu-write-port /m68hc11");
229 cpu
->hw_cpu
= sim_hw_parse (sd
, "/m68hc11");
233 cpu
->cpu_interpretor
= cpu_interp_m6812
;
234 if (hw_tree_find_property (device_tree
, "/m68hc12/reg") == 0)
236 /* Allocate core external memory. */
237 sim_do_commandf (sd
, "memory region 0x%lx@%d,0x%lx",
238 0x8000, M6811_RAM_LEVEL
, 0x8000);
239 sim_do_commandf (sd
, "memory region 0x000@%d,0x8000",
241 if (cpu
->bank_start
< cpu
->bank_end
)
243 sim_do_commandf (sd
, "memory region 0x%lx@%d,0x100000",
244 cpu
->bank_virtual
, M6811_RAM_LEVEL
);
245 sim_hw_parse (sd
, "/m68hc12/use_bank 1");
247 sim_hw_parse (sd
, "/m68hc12/reg 0x0 0x3FF");
250 if (!hw_tree_find_property (device_tree
, "/m68hc12/m68hc12sio@1/reg"))
252 sim_hw_parse (sd
, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
253 sim_hw_parse (sd
, "/m68hc12/m68hc12sio@1/backend stdio");
254 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
256 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12tim/reg") == 0)
258 /* M68hc11 Timer configuration. */
259 sim_hw_parse (sd
, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
260 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
261 sim_hw_parse (sd
, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
264 /* Create the SPI device. */
265 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12spi/reg") == 0)
267 sim_hw_parse (sd
, "/m68hc12/m68hc12spi/reg 0x28 0x3");
268 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
270 if (hw_tree_find_property (device_tree
, "/m68hc12/nvram/reg") == 0)
272 /* M68hc11 persistent ram configuration. */
273 sim_hw_parse (sd
, "/m68hc12/nvram/reg 0x2000 8192");
274 sim_hw_parse (sd
, "/m68hc12/nvram/file m68hc12.ram");
275 sim_hw_parse (sd
, "/m68hc12/nvram/mode save-modified");
277 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12eepr/reg") == 0)
279 sim_hw_parse (sd
, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
280 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
283 sim_hw_parse (sd
, "/m68hc12 > port-a cpu-write-port /m68hc12");
284 sim_hw_parse (sd
, "/m68hc12 > port-b cpu-write-port /m68hc12");
285 sim_hw_parse (sd
, "/m68hc12 > port-c cpu-write-port /m68hc12");
286 sim_hw_parse (sd
, "/m68hc12 > port-d cpu-write-port /m68hc12");
287 cpu
->hw_cpu
= sim_hw_parse (sd
, "/m68hc12");
292 /* Get the memory bank parameters by looking at the global symbols
293 defined by the linker. */
295 sim_get_bank_parameters (SIM_DESC sd
, bfd
* abfd
)
299 long symbol_count
, i
;
304 cpu
= STATE_CPU (sd
, 0);
306 symsize
= bfd_get_symtab_upper_bound (abfd
);
309 sim_io_eprintf (sd
, "Cannot read symbols of program");
312 asymbols
= (asymbol
**) xmalloc (symsize
);
313 symbol_count
= bfd_canonicalize_symtab (abfd
, asymbols
);
314 if (symbol_count
< 0)
316 sim_io_eprintf (sd
, "Cannot read symbols of program");
321 for (i
= 0, current
= asymbols
; i
< symbol_count
; i
++, current
++)
323 const char* name
= bfd_asymbol_name (*current
);
325 if (strcmp (name
, BFD_M68HC11_BANK_START_NAME
) == 0)
327 cpu
->bank_start
= bfd_asymbol_value (*current
);
329 else if (strcmp (name
, BFD_M68HC11_BANK_SIZE_NAME
) == 0)
331 size
= bfd_asymbol_value (*current
);
333 else if (strcmp (name
, BFD_M68HC11_BANK_VIRTUAL_NAME
) == 0)
335 cpu
->bank_virtual
= bfd_asymbol_value (*current
);
340 cpu
->bank_end
= cpu
->bank_start
+ size
;
342 for (; size
> 1; size
>>= 1)
349 sim_prepare_for_program (SIM_DESC sd
, bfd
* abfd
)
354 cpu
= STATE_CPU (sd
, 0);
360 if (bfd_get_flavour (abfd
) == bfd_target_elf_flavour
)
361 elf_flags
= elf_elfheader (abfd
)->e_flags
;
363 cpu
->cpu_elf_start
= bfd_get_start_address (abfd
);
364 /* See if any section sets the reset address */
365 cpu
->cpu_use_elf_start
= 1;
366 for (s
= abfd
->sections
; s
&& cpu
->cpu_use_elf_start
; s
= s
->next
)
368 if (s
->flags
& SEC_LOAD
)
372 size
= bfd_get_section_size (s
);
377 if (STATE_LOAD_AT_LMA_P (sd
))
378 lma
= bfd_section_lma (abfd
, s
);
380 lma
= bfd_section_vma (abfd
, s
);
382 if (lma
<= 0xFFFE && lma
+size
>= 0x10000)
383 cpu
->cpu_use_elf_start
= 0;
388 if (elf_flags
& E_M68HC12_BANKS
)
390 if (sim_get_bank_parameters (sd
, abfd
) != 0)
391 sim_io_eprintf (sd
, "Memory bank parameters are not initialized\n");
395 if (!sim_hw_configure (sd
))
398 /* reset all state information */
399 sim_board_reset (sd
);
405 m68hc11_pc_get (sim_cpu
*cpu
)
407 return cpu_get_pc (cpu
);
411 m68hc11_pc_set (sim_cpu
*cpu
, sim_cia pc
)
413 cpu_set_pc (cpu
, pc
);
416 static int m68hc11_reg_fetch (SIM_CPU
*, int, unsigned char *, int);
417 static int m68hc11_reg_store (SIM_CPU
*, int, unsigned char *, int);
420 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
421 bfd
*abfd
, char **argv
)
427 sd
= sim_state_alloc (kind
, callback
);
429 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
431 /* The cpu data is kept in a separately allocated chunk of memory. */
432 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
438 cpu
= STATE_CPU (sd
, 0);
440 /* for compatibility */
441 current_alignment
= NONSTRICT_ALIGNMENT
;
442 current_target_byte_order
= BIG_ENDIAN
;
444 cpu_initialize (sd
, cpu
);
446 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
452 /* getopt will print the error message so we just have to exit if this fails.
453 FIXME: Hmmm... in the case of gdb we need getopt to call
455 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
457 /* Uninstall the modules to avoid memory leaks,
458 file descriptor leaks, etc. */
463 /* Check for/establish the a reference program image. */
464 if (sim_analyze_program (sd
,
465 (STATE_PROG_ARGV (sd
) != NULL
466 ? *STATE_PROG_ARGV (sd
)
467 : NULL
), abfd
) != SIM_RC_OK
)
473 /* Establish any remaining configuration options. */
474 if (sim_config (sd
) != SIM_RC_OK
)
480 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
482 /* Uninstall the modules to avoid memory leaks,
483 file descriptor leaks, etc. */
487 if (sim_prepare_for_program (sd
, abfd
) != SIM_RC_OK
)
493 /* CPU specific initialization. */
494 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
496 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
498 CPU_REG_FETCH (cpu
) = m68hc11_reg_fetch
;
499 CPU_REG_STORE (cpu
) = m68hc11_reg_store
;
500 CPU_PC_FETCH (cpu
) = m68hc11_pc_get
;
501 CPU_PC_STORE (cpu
) = m68hc11_pc_set
;
507 /* Generic implementation of sim_engine_run that works within the
508 sim_engine setjmp/longjmp framework. */
511 sim_engine_run (SIM_DESC sd
,
512 int next_cpu_nr
, /* ignore */
513 int nr_cpus
, /* ignore */
514 int siggnal
) /* ignore */
518 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
519 cpu
= STATE_CPU (sd
, 0);
522 cpu_single_step (cpu
);
524 /* process any events */
525 if (sim_events_tickn (sd
, cpu
->cpu_current_cycle
))
527 sim_events_process (sd
);
533 sim_info (SIM_DESC sd
, int verbose
)
535 const char *cpu_type
;
536 const struct bfd_arch_info
*arch
;
538 /* Nothing to do if there is no verbose flag set. */
539 if (verbose
== 0 && STATE_VERBOSE_P (sd
) == 0)
542 arch
= STATE_ARCHITECTURE (sd
);
543 if (arch
->arch
== bfd_arch_m68hc11
)
548 sim_io_eprintf (sd
, "Simulator info:\n");
549 sim_io_eprintf (sd
, " CPU Motorola %s\n", cpu_type
);
550 sim_get_info (sd
, 0);
551 sim_module_info (sd
, verbose
|| STATE_VERBOSE_P (sd
));
555 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
556 char **argv
, char **env
)
558 return sim_prepare_for_program (sd
, abfd
);
562 m68hc11_reg_fetch (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
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 m68hc11_reg_store (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
632 val
= (val
<< 8) | *memory
;
637 cpu_set_d (cpu
, val
);
641 cpu_set_a (cpu
, val
);
645 cpu_set_b (cpu
, val
);
649 cpu_set_x (cpu
, val
);
653 cpu_set_y (cpu
, val
);
657 cpu_set_sp (cpu
, val
);
661 cpu_set_pc (cpu
, val
);
665 cpu_set_ccr (cpu
, val
);
669 cpu_set_page (cpu
, val
);