1 /* interp.c -- Simulator for Motorola 68HC11
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@worldnet.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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "sim-assert.h"
24 #include "sim-options.h"
26 #include "hw-device.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
;
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");
200 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11sio/reg") == 0)
202 sim_hw_parse (sd
, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
203 sim_hw_parse (sd
, "/m68hc11/m68hc11sio/backend stdio");
204 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
206 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11tim/reg") == 0)
208 /* M68hc11 Timer configuration. */
209 sim_hw_parse (sd
, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
210 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
213 /* Create the SPI device. */
214 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11spi/reg") == 0)
216 sim_hw_parse (sd
, "/m68hc11/m68hc11spi/reg 0x28 0x3");
217 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
219 if (hw_tree_find_property (device_tree
, "/m68hc11/nvram/reg") == 0)
221 /* M68hc11 persistent ram configuration. */
222 sim_hw_parse (sd
, "/m68hc11/nvram/reg 0x0 256");
223 sim_hw_parse (sd
, "/m68hc11/nvram/file m68hc11.ram");
224 sim_hw_parse (sd
, "/m68hc11/nvram/mode save-modified");
225 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
227 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11eepr/reg") == 0)
229 sim_hw_parse (sd
, "/m68hc11/m68hc11eepr/reg 0xb000 512");
230 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
235 cpu
->cpu_interpretor
= cpu_interp_m6812
;
236 if (hw_tree_find_property (device_tree
, "/m68hc12/reg") == 0)
238 /* Allocate core external memory. */
239 sim_do_commandf (sd
, "memory region 0x%lx@%d,0x%lx",
240 0x8000, M6811_RAM_LEVEL
, 0x8000);
241 sim_do_commandf (sd
, "memory region 0x000@%d,0x8000",
244 sim_hw_parse (sd
, "/m68hc12/reg 0x0 0x3FF");
247 if (!hw_tree_find_property (device_tree
, "/m68hc12/m68hc12sio@1/reg"))
249 sim_hw_parse (sd
, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
250 sim_hw_parse (sd
, "/m68hc12/m68hc12sio@1/backend stdio");
251 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
253 if (!hw_tree_find_property (device_tree
, "/m68hc12/m68hc12sio@2/reg"))
255 sim_hw_parse (sd
, "/m68hc12/m68hc12sio@2/reg 0xC8 0x8");
256 sim_hw_parse (sd
, "/m68hc12/m68hc12sio@2/backend tcp");
257 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@2");
259 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12tim/reg") == 0)
261 /* M68hc11 Timer configuration. */
262 sim_hw_parse (sd
, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
263 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
266 /* Create the SPI device. */
267 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12spi/reg") == 0)
269 sim_hw_parse (sd
, "/m68hc12/m68hc12spi/reg 0x28 0x3");
270 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
272 if (hw_tree_find_property (device_tree
, "/m68hc12/nvram/reg") == 0)
274 /* M68hc11 persistent ram configuration. */
275 sim_hw_parse (sd
, "/m68hc12/nvram/reg 0x2000 8192");
276 sim_hw_parse (sd
, "/m68hc12/nvram/file m68hc12.ram");
277 sim_hw_parse (sd
, "/m68hc12/nvram/mode save-modified");
279 if (hw_tree_find_property (device_tree
, "/m68hc12/m68hc12eepr/reg") == 0)
281 sim_hw_parse (sd
, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
282 sim_hw_parse (sd
, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
289 sim_prepare_for_program (SIM_DESC sd
, struct _bfd
* abfd
)
293 cpu
= STATE_CPU (sd
, 0);
295 sim_hw_configure (sd
);
298 cpu
->cpu_elf_start
= bfd_get_start_address (abfd
);
301 /* reset all state information */
302 sim_board_reset (sd
);
308 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
309 struct _bfd
*abfd
, char **argv
)
314 struct hw
*device_tree
;
316 sd
= sim_state_alloc (kind
, callback
);
317 cpu
= STATE_CPU (sd
, 0);
319 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
321 /* for compatibility */
322 current_alignment
= NONSTRICT_ALIGNMENT
;
323 current_target_byte_order
= BIG_ENDIAN
;
325 cpu_initialize (sd
, cpu
);
327 cpu
->cpu_use_elf_start
= 1;
328 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
334 /* getopt will print the error message so we just have to exit if this fails.
335 FIXME: Hmmm... in the case of gdb we need getopt to call
337 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
339 /* Uninstall the modules to avoid memory leaks,
340 file descriptor leaks, etc. */
345 /* Check for/establish the a reference program image. */
346 if (sim_analyze_program (sd
,
347 (STATE_PROG_ARGV (sd
) != NULL
348 ? *STATE_PROG_ARGV (sd
)
349 : NULL
), abfd
) != SIM_RC_OK
)
355 /* Establish any remaining configuration options. */
356 if (sim_config (sd
) != SIM_RC_OK
)
362 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
364 /* Uninstall the modules to avoid memory leaks,
365 file descriptor leaks, etc. */
370 sim_hw_configure (sd
);
372 /* Fudge our descriptor. */
378 sim_close (SIM_DESC sd
, int quitting
)
380 /* shut down modules */
381 sim_module_uninstall (sd
);
383 /* Ensure that any resources allocated through the callback
384 mechanism are released: */
385 sim_io_shutdown (sd
);
387 /* FIXME - free SD */
393 sim_set_profile (int n
)
398 sim_set_profile_size (int n
)
402 /* Generic implementation of sim_engine_run that works within the
403 sim_engine setjmp/longjmp framework. */
406 sim_engine_run (SIM_DESC sd
,
407 int next_cpu_nr
, /* ignore */
408 int nr_cpus
, /* ignore */
409 int siggnal
) /* ignore */
413 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
414 cpu
= STATE_CPU (sd
, 0);
417 cpu_single_step (cpu
);
419 /* process any events */
420 if (sim_events_tickn (sd
, cpu
->cpu_current_cycle
))
422 sim_events_process (sd
);
428 sim_trace (SIM_DESC sd
)
430 sim_resume (sd
, 0, 0);
435 sim_info (SIM_DESC sd
, int verbose
)
437 const char *cpu_type
;
438 const struct bfd_arch_info
*arch
;
440 arch
= STATE_ARCHITECTURE (sd
);
441 if (arch
->arch
== bfd_arch_m68hc11
)
446 sim_io_eprintf (sd
, "Simulator info:\n");
447 sim_io_eprintf (sd
, " CPU Motorola %s\n", cpu_type
);
448 sim_get_info (sd
, 0);
449 sim_module_info (sd
, verbose
|| STATE_VERBOSE_P (sd
));
453 sim_create_inferior (SIM_DESC sd
, struct _bfd
*abfd
,
454 char **argv
, char **env
)
456 return sim_prepare_for_program (sd
, abfd
);
461 sim_set_callbacks (host_callback
*p
)
463 /* m6811_callback = p; */
468 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
473 cpu
= STATE_CPU (sd
, 0);
477 val
= cpu_get_a (cpu
);
481 val
= cpu_get_b (cpu
);
485 val
= cpu_get_d (cpu
);
489 val
= cpu_get_x (cpu
);
493 val
= cpu_get_y (cpu
);
497 val
= cpu_get_sp (cpu
);
501 val
= cpu_get_pc (cpu
);
505 val
= cpu_get_ccr (cpu
);
512 memory
[0] = val
>> 8;
513 memory
[1] = val
& 0x0FF;
518 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
523 cpu
= STATE_CPU (sd
, 0);
527 val
= (val
<< 8) | *memory
;
532 cpu_set_d (cpu
, val
);
536 cpu_set_a (cpu
, val
);
540 cpu_set_b (cpu
, val
);
544 cpu_set_x (cpu
, val
);
548 cpu_set_y (cpu
, val
);
552 cpu_set_sp (cpu
, val
);
556 cpu_set_pc (cpu
, val
);
560 cpu_set_ccr (cpu
, val
);
577 sim_do_command (SIM_DESC sd
, char *cmd
)
579 char *mm_cmd
= "memory-map";
580 char *int_cmd
= "interrupt";
583 cpu
= STATE_CPU (sd
, 0);
584 /* Commands available from GDB: */
585 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
587 if (strncmp (cmd
, "info", sizeof ("info") - 1) == 0)
588 sim_get_info (sd
, &cmd
[4]);
589 else if (strncmp (cmd
, "frame", sizeof ("frame") - 1) == 0)
590 cpu_print_frame (sd
, STATE_CPU (sd
, 0));
591 else if (strncmp (cmd
, mm_cmd
, strlen (mm_cmd
) == 0))
593 "`memory-map' command replaced by `sim memory'\n");
594 else if (strncmp (cmd
, int_cmd
, strlen (int_cmd
)) == 0)
595 sim_io_eprintf (sd
, "`interrupt' command replaced by `sim watch'\n");
597 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);
600 /* If the architecture changed, re-configure. */
601 if (STATE_ARCHITECTURE (sd
) != cpu
->cpu_configured_arch
)
602 sim_hw_configure (sd
);